From 379e41eac0655769339ca03ab72a404f5662b1f5 Mon Sep 17 00:00:00 2001 From: Elpacos Date: Mon, 23 Dec 2024 10:44:21 +0100 Subject: [PATCH 01/18] chore: setup and coverage --- .gitignore | 9 +- .../CryticToFoundry.t.sol | 87 ++++ .../HandlerAggregator.t.sol | 25 + test/enigma-dark-invariants/Invariants.t.sol | 22 + test/enigma-dark-invariants/README.md | 37 ++ test/enigma-dark-invariants/Setup.t.sol | 219 +++++++++ .../SpecAggregator.t.sol | 44 ++ test/enigma-dark-invariants/Tester.t.sol | 27 ++ .../_config/echidna_config.yaml | 59 +++ .../_config/echidna_config_ci.yaml | 59 +++ .../base/BaseHandler.t.sol | 87 ++++ .../base/BaseHooks.t.sol | 14 + .../base/BaseStorage.t.sol | 110 +++++ .../base/BaseTest.t.sol | 106 +++++ .../base/ProtocolAssertions.t.sol | 10 + .../docs/internal-docs.md | 292 ++++++++++++ .../docs/invariant-suite-inheritance.png | Bin 0 -> 480992 bytes .../docs/invariant-suite-overview.png | Bin 0 -> 238434 bytes test/enigma-dark-invariants/docs/overview.md | 165 +++++++ .../handlers/euler/EVCHandler.t.sol | 145 ++++++ .../handlers/interfaces/IERC4626Handler.sol | 7 + .../simulators/DonationAttackHandler.t.sol | 46 ++ .../simulators/PriceOracleHandler.t.sol | 31 ++ .../handlers/standard/ERC20Handler.t.sol | 95 ++++ .../handlers/standard/ERC4626Handler.t.sol | 103 ++++ .../handlers/swap/MaglevHandler.t.sol | 47 ++ .../helpers/extended/.gitkeep | 0 .../hooks/DefaultBeforeAfterHooks.t.sol | 85 ++++ .../hooks/HookAggregator.t.sol | 55 +++ .../invariants/BaseInvariants.t.sol | 23 + .../specs/InvariantsSpec.t.sol | 23 + .../specs/NonRevertPropertiesSpec.t.sol | 23 + .../specs/PostconditionsSpec.t.sol | 30 ++ test/enigma-dark-invariants/utils/Actor.sol | 60 +++ .../utils/Create2Factory.sol | 32 ++ .../utils/DeployPermit2.sol | 22 + test/enigma-dark-invariants/utils/Pretty.sol | 142 ++++++ .../utils/PropertiesAsserts.sol | 410 ++++++++++++++++ .../utils/PropertiesConstants.sol | 11 + .../utils/StdAsserts.sol | 443 ++++++++++++++++++ .../utils/mocks/MockPriceOracle.sol | 80 ++++ .../utils/mocks/TestERC20.sol | 18 + 42 files changed, 3302 insertions(+), 1 deletion(-) create mode 100644 test/enigma-dark-invariants/CryticToFoundry.t.sol create mode 100644 test/enigma-dark-invariants/HandlerAggregator.t.sol create mode 100644 test/enigma-dark-invariants/Invariants.t.sol create mode 100644 test/enigma-dark-invariants/README.md create mode 100644 test/enigma-dark-invariants/Setup.t.sol create mode 100644 test/enigma-dark-invariants/SpecAggregator.t.sol create mode 100644 test/enigma-dark-invariants/Tester.t.sol create mode 100644 test/enigma-dark-invariants/_config/echidna_config.yaml create mode 100644 test/enigma-dark-invariants/_config/echidna_config_ci.yaml create mode 100644 test/enigma-dark-invariants/base/BaseHandler.t.sol create mode 100644 test/enigma-dark-invariants/base/BaseHooks.t.sol create mode 100644 test/enigma-dark-invariants/base/BaseStorage.t.sol create mode 100644 test/enigma-dark-invariants/base/BaseTest.t.sol create mode 100644 test/enigma-dark-invariants/base/ProtocolAssertions.t.sol create mode 100644 test/enigma-dark-invariants/docs/internal-docs.md create mode 100644 test/enigma-dark-invariants/docs/invariant-suite-inheritance.png create mode 100644 test/enigma-dark-invariants/docs/invariant-suite-overview.png create mode 100644 test/enigma-dark-invariants/docs/overview.md create mode 100644 test/enigma-dark-invariants/handlers/euler/EVCHandler.t.sol create mode 100644 test/enigma-dark-invariants/handlers/interfaces/IERC4626Handler.sol create mode 100644 test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol create mode 100644 test/enigma-dark-invariants/handlers/simulators/PriceOracleHandler.t.sol create mode 100644 test/enigma-dark-invariants/handlers/standard/ERC20Handler.t.sol create mode 100644 test/enigma-dark-invariants/handlers/standard/ERC4626Handler.t.sol create mode 100644 test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol create mode 100644 test/enigma-dark-invariants/helpers/extended/.gitkeep create mode 100644 test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol create mode 100644 test/enigma-dark-invariants/hooks/HookAggregator.t.sol create mode 100644 test/enigma-dark-invariants/invariants/BaseInvariants.t.sol create mode 100644 test/enigma-dark-invariants/specs/InvariantsSpec.t.sol create mode 100644 test/enigma-dark-invariants/specs/NonRevertPropertiesSpec.t.sol create mode 100644 test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol create mode 100644 test/enigma-dark-invariants/utils/Actor.sol create mode 100644 test/enigma-dark-invariants/utils/Create2Factory.sol create mode 100644 test/enigma-dark-invariants/utils/DeployPermit2.sol create mode 100644 test/enigma-dark-invariants/utils/Pretty.sol create mode 100644 test/enigma-dark-invariants/utils/PropertiesAsserts.sol create mode 100644 test/enigma-dark-invariants/utils/PropertiesConstants.sol create mode 100644 test/enigma-dark-invariants/utils/StdAsserts.sol create mode 100644 test/enigma-dark-invariants/utils/mocks/MockPriceOracle.sol create mode 100644 test/enigma-dark-invariants/utils/mocks/TestERC20.sol diff --git a/.gitignore b/.gitignore index 64c78d5..2fc9544 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,11 @@ out/ .env # Coverage file -lcov.info \ No newline at end of file +lcov.info + +# echidna +_corpus/ +crytic-export/ + +.DS_Store +.vscode \ No newline at end of file diff --git a/test/enigma-dark-invariants/CryticToFoundry.t.sol b/test/enigma-dark-invariants/CryticToFoundry.t.sol new file mode 100644 index 0000000..fba2ad2 --- /dev/null +++ b/test/enigma-dark-invariants/CryticToFoundry.t.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Libraries +import "forge-std/Test.sol"; +import "forge-std/console.sol"; + +// Contracts +import {Invariants} from "./Invariants.t.sol"; +import {Setup} from "./Setup.t.sol"; + +/* + * Test suite that converts from "fuzz tests" to foundry "unit tests" + * The objective is to go from random values to hardcoded values that can be analyzed more easily + */ +contract CryticToFoundry is Invariants, Setup { + CryticToFoundry Tester = this; + + modifier setup() override { + _; + } + + function setUp() public { + // Deploy protocol contracts + _setUp(); + + // Initialize handler contracts + _setUpHandlers(); + + // Initialize hook contracts + _setUpHooks(); + + /// @dev fixes the actor to the first user + actor = actors[USER1]; + + vm.warp(101007); + } + + /// @dev Needed in order for foundry to recognise the contract as a test, faster debugging + function testAux() public {} + + /////////////////////////////////////////////////////////////////////////////////////////////// + // POSTCONDITIONS REPLAY // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // INVARIANTS REPLAY // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // BROKEN INVARIANTS REPLAY // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HELPERS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @notice Fast forward the time and set up an actor, + /// @dev Use for ECHIDNA call-traces + function _delay(uint256 _seconds) internal { + vm.warp(block.timestamp + _seconds); + } + + /// @notice Set up an actor + function _setUpActor(address _origin) internal { + actor = actors[_origin]; + } + + /// @notice Set up an actor and fast forward the time + /// @dev Use for ECHIDNA call-traces + function _setUpActorAndDelay(address _origin, uint256 _seconds) internal { + actor = actors[_origin]; + vm.warp(block.timestamp + _seconds); + } + + /// @notice Set up a specific block and actor + function _setUpBlockAndActor(uint256 _block, address _user) internal { + vm.roll(_block); + actor = actors[_user]; + } + + /// @notice Set up a specific timestamp and actor + function _setUpTimestampAndActor(uint256 _timestamp, address _user) internal { + vm.warp(_timestamp); + actor = actors[_user]; + } +} diff --git a/test/enigma-dark-invariants/HandlerAggregator.t.sol b/test/enigma-dark-invariants/HandlerAggregator.t.sol new file mode 100644 index 0000000..5cf81af --- /dev/null +++ b/test/enigma-dark-invariants/HandlerAggregator.t.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// modules Actions Handler contracts, +import {EVCHandler} from "./handlers/euler/EVCHandler.t.sol"; +import {ERC20Handler} from "./handlers/standard/ERC20Handler.t.sol"; +import {ERC4626Handler} from "./handlers/standard/ERC4626Handler.t.sol"; +import {MaglevHandler} from "./handlers/swap/MaglevHandler.t.sol"; + +// Simulator Handler contracts, +import {DonationAttackHandler} from "./handlers/simulators/DonationAttackHandler.t.sol"; +import {PriceOracleHandler} from "./handlers/simulators/PriceOracleHandler.t.sol"; + +/// @notice Helper contract to aggregate all handler contracts, inherited in BaseInvariants +abstract contract HandlerAggregator is + EVCHandler, // Euler handlers + ERC20Handler, // Module handlers + ERC4626Handler, + MaglevHandler, + DonationAttackHandler, // Simulator handlers + PriceOracleHandler +{ + /// @notice Helper function in case any handler requires additional setup + function _setUpHandlers() internal {} +} diff --git a/test/enigma-dark-invariants/Invariants.t.sol b/test/enigma-dark-invariants/Invariants.t.sol new file mode 100644 index 0000000..f01f07f --- /dev/null +++ b/test/enigma-dark-invariants/Invariants.t.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Interfaces +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +// Invariant Contracts +import {BaseInvariants} from "./invariants/BaseInvariants.t.sol"; + +/// @title Invariants +/// @notice Wrappers for the protocol invariants implemented in each invariants contract +/// @dev recognised by Echidna when property mode is activated +/// @dev Inherits BaseInvariants +abstract contract Invariants is BaseInvariants { + /////////////////////////////////////////////////////////////////////////////////////////////// + // BASE INVARIANTS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function echidna_BASE_ASSETS_INVARIANTS() public returns (bool) { + return true; + } +} diff --git a/test/enigma-dark-invariants/README.md b/test/enigma-dark-invariants/README.md new file mode 100644 index 0000000..ff98c53 --- /dev/null +++ b/test/enigma-dark-invariants/README.md @@ -0,0 +1,37 @@ +# Actor Based Invariant Testing Suite + +Enigma Dark suite + +
+ +Developed by [vnmrtz.eth](https://x.com/vn_martinez_) from [Enigma Dark](https://www.enigmadark.com/). + +
+ +The Actor Based Invariant Testing Suite is a framework for performing comprehensive invariant testing of the Euler Maglev protocol. Using an actor-based model, it simulates realistic scenarios with various entities interacting with the system, ensuring that protocol invariants and postconditions hold under an extensive range of conditions. + +The suite is designed to support multi-actor tooling, randomizing actions, parameters, actor roles, and asset selection to explore edge cases and ensure the robustness of a protocol. + +# Specifications + +Extensive documentation regarding the architecture and design of the suite can be found [HERE](./docs/overview.md). + +Further documentation outlining the properties of the system (both invariants and postconditions) can be found [HERE](./specs/). + +# Tooling + +The suite has been developed and tested using the following tools: + +- [Echidna](https://github.com/crytic/echidna): A battle tested property-based testing tool for Ethereum smart contracts. + +# Setup Instructions: + +Instructions for setting up the project and running the testing suite with echidna are available [HERE](./docs/internal-docs.md). + +## Additional notes + +- Ensure you have the latest version of dependencies both tooling and protocol dependencies installed before running the tests. +- The suite is designed to be modular and extensible, allowing for easy integration of new properties and actors. +- The suite supports integration with github actions, allowing for automated testing as part of the development workflow. + +This suite was developed by Enigma Dark after being engaged by Euler Labs to provide security services for the Euler v2 protocol, ensuring that best practices in security and testing are satisfied. diff --git a/test/enigma-dark-invariants/Setup.t.sol b/test/enigma-dark-invariants/Setup.t.sol new file mode 100644 index 0000000..709b4f6 --- /dev/null +++ b/test/enigma-dark-invariants/Setup.t.sol @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Utils +import "forge-std/console.sol"; + +// Libraries +import {DeployPermit2} from "./utils/DeployPermit2.sol"; + +// Contracts +import {EthereumVaultConnector} from "ethereum-vault-connector/EthereumVaultConnector.sol"; +import {GenericFactory} from "evk/GenericFactory/GenericFactory.sol"; +import {ProtocolConfig} from "evk/ProtocolConfig/ProtocolConfig.sol"; +import {SequenceRegistry} from "evk/SequenceRegistry/SequenceRegistry.sol"; +import {Base} from "evk/EVault/shared/Base.sol"; +import {Dispatch} from "evk/EVault/Dispatch.sol"; +import {EVault} from "evk/EVault/EVault.sol"; +import {MaglevBase} from "src/MaglevBase.sol"; +import {MaglevEulerSwap as Maglev} from "src/MaglevEulerSwap.sol"; + +// Modules +import {Initialize} from "evk/EVault/modules/Initialize.sol"; +import {Token} from "evk/EVault/modules/Token.sol"; +import {Vault} from "evk/EVault/modules/Vault.sol"; +import {Borrowing} from "evk/EVault/modules/Borrowing.sol"; +import {Liquidation} from "evk/EVault/modules/Liquidation.sol"; +import {BalanceForwarder} from "evk/EVault/modules/BalanceForwarder.sol"; +import {Governance} from "evk/EVault/modules/Governance.sol"; +import {RiskManager} from "evk/EVault/modules/RiskManager.sol"; +import {MockBalanceTracker} from "evk/../test/mocks/MockBalanceTracker.sol"; + +// Interfaces +import {IEVault} from "evk/EVault/IEVault.sol"; +import {IRMTestDefault} from "evk-test/mocks/IRMTestDefault.sol"; +import {IMaglevBase} from "src/interfaces/IMaglevBase.sol"; + +// Test Contracts +import {TestERC20} from "test/enigma-dark-invariants/utils/mocks/TestERC20.sol"; +import {BaseTest} from "test/enigma-dark-invariants/base/BaseTest.t.sol"; +import {MockPriceOracle} from "./utils/mocks/MockPriceOracle.sol"; +import {Actor} from "./utils/Actor.sol"; + +/// @notice Setup contract for the invariant test Suite, inherited by Tester +contract Setup is BaseTest { + function _setUp() internal { + // Deploy protocol contracts and protocol actors + _deployEulerEnvContracts(); + + // Deploy vaults + _deployVaults(); + + // Deploy actors + _setUpActors(); + + // Deploy and setup maglev + _deployMaglev(); + } + + /// @notice Deploy euler env contracts + function _deployEulerEnvContracts() internal { + // Deploy the EVC + evc = new EthereumVaultConnector(); + + // Deploy permit2 contract + permit2 = DeployPermit2.deployPermit2(); + + // Setup fee recipient + feeRecipient = _makeAddr("feeRecipient"); + protocolConfig = new ProtocolConfig(address(this), feeRecipient); + + // Deploy the oracle and integrations + balanceTracker = address(new MockBalanceTracker()); + oracle = new MockPriceOracle(); + sequenceRegistry = address(new SequenceRegistry()); + } + + function _deployVaults() internal { + // Deploy the modules + Base.Integrations memory integrations = + Base.Integrations(address(evc), address(protocolConfig), sequenceRegistry, balanceTracker, permit2); + + Dispatch.DeployedModules memory modules = Dispatch.DeployedModules({ + initialize: address(new Initialize(integrations)), + token: address(new Token(integrations)), + vault: address(new Vault(integrations)), + borrowing: address(new Borrowing(integrations)), + liquidation: address(new Liquidation(integrations)), + riskManager: address(new RiskManager(integrations)), + balanceForwarder: address(new BalanceForwarder(integrations)), + governance: address(new Governance(integrations)) + }); + + // Deploy the vault implementation + address evaultImpl = address(new EVault(integrations, modules)); + + // Deploy the vault factory and set the implementation + factory = new GenericFactory(address(this)); + factory.setImplementation(evaultImpl); + + // Deploy base assets + assetTST = new TestERC20("Test Token", "TST", 18); + baseAssets.push(address(assetTST)); + + assetTST2 = new TestERC20("Test Token 2", "TST2", 18); + baseAssets.push(address(assetTST2)); + + // Deploy the vaults + eTST = _deployEVault(address(assetTST)); + vaults.push(address(eTST)); + + eTST2 = _deployEVault(address(assetTST2)); + vaults.push(address(eTST2)); + } + + function _deployMaglev() internal { + // Setup maglev lp as the first actor + maglevLp = address(actors[USER1]); + + // Setup the maglev params∫ + MaglevBase.BaseParams memory baseParams = MaglevBase.BaseParams({ + evc: address(evc), + vault0: address(eTST), + vault1: address(eTST2), + myAccount: maglevLp, + debtLimit0: 50e18, // TODO tweak these numbers + debtLimit1: 50e18, + fee: 0 + }); + + // Deploy the maglev contract + maglev = IMaglevBase( + address( + new Maglev( + baseParams, + Maglev.EulerSwapParams({priceX: 1e18, priceY: 1e18, concentrationX: 0.4e18, concentrationY: 0.85e18}) + ) + ) + ); + + // Set maglev as operator for the lp and call configure + vm.prank(maglevLp); + evc.setAccountOperator(maglevLp, address(maglev), true); + maglev.configure(); + + // Setup actors token approvals to maglev + address[] memory contracts = new address[](1); + contracts[0] = address(maglev); + + _setupActorApprovals(baseAssets, contracts); + } + + function _deployEVault(address asset) internal returns (IEVault eVault) { + // Deploy the eTST + eVault = IEVault(factory.createProxy(address(0), true, abi.encodePacked(asset, address(oracle), address(1)))); + + // Configure the vault + eVault.setHookConfig(address(0), 0); + eVault.setInterestRateModel(address(new IRMTestDefault())); + eVault.setMaxLiquidationDiscount(0.2e4); + eVault.setFeeReceiver(feeRecipient); + } + + /// @notice Deploy protocol actors and initialize their balances + function _setUpActors() internal { + // Initialize the three actors of the fuzzers + address[] memory addresses = new address[](3); + addresses[0] = USER1; + addresses[1] = USER2; + addresses[2] = USER3; + + // Initialize the tokens array + address[] memory tokens = new address[](2); + tokens[0] = address(assetTST); + tokens[1] = address(assetTST2); + + address[] memory contracts_ = new address[](2); + contracts_[0] = address(eTST); + contracts_[1] = address(eTST2); + + for (uint256 i; i < NUMBER_OF_ACTORS; i++) { + // Deploy actor proxies and approve system contracts_ + address _actor = _setUpActor(addresses[i], tokens, contracts_); + + // Mint initial balances to actors + for (uint256 j = 0; j < tokens.length; j++) { + TestERC20 _token = TestERC20(tokens[j]); + _token.mint(_actor, INITIAL_BALANCE); + } + actorAddresses.push(_actor); + } + } + + /// @notice Deploy an actor proxy contract for a user address + /// @param userAddress Address of the user + /// @param tokens Array of token addresses + /// @param contracts_ Array of contract addresses to aprove tokens to + /// @return actorAddress Address of the deployed actor + function _setUpActor(address userAddress, address[] memory tokens, address[] memory contracts_) + internal + returns (address actorAddress) + { + bool success; + Actor _actor = new Actor(tokens, contracts_); + actors[userAddress] = _actor; + (success,) = address(_actor).call{value: INITIAL_ETH_BALANCE}(""); + assert(success); + actorAddress = address(_actor); + } + + function _setupActorApprovals(address[] memory tokens, address[] memory contracts_) internal { + for (uint256 i; i < actorAddresses.length; i++) { + for (uint256 j; j < tokens.length; j++) { + for (uint256 k; k < contracts_.length; k++) { + _approve(tokens[j], actorAddresses[i], contracts_[k], type(uint256).max); + } + } + } + } +} diff --git a/test/enigma-dark-invariants/SpecAggregator.t.sol b/test/enigma-dark-invariants/SpecAggregator.t.sol new file mode 100644 index 0000000..09b29a9 --- /dev/null +++ b/test/enigma-dark-invariants/SpecAggregator.t.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Test Contracts +import {InvariantsSpec} from "./specs/InvariantsSpec.t.sol"; +import {PostconditionsSpec} from "./specs/PostconditionsSpec.t.sol"; +import {NonRevertPropertiesSpec} from "./specs/NonRevertPropertiesSpec.t.sol"; + +/// @title SpecAggregator +/// @notice Helper contract to aggregate all spec contracts, inherited in BaseHooks +/// @dev inherits InvariantsSpec, PostconditionsSpec +abstract contract SpecAggregator is InvariantsSpec, PostconditionsSpec, NonRevertPropertiesSpec { +/////////////////////////////////////////////////////////////////////////////////////////////// +// PROPERTY TYPES // +/////////////////////////////////////////////////////////////////////////////////////////////// + +/// In this invariant testing framework, there are two types of properties: + +/// - INVARIANTS (INV): +/// - Properties that should always hold true in the system. +/// - Implemented in the /invariants folder. + +/// - POSTCONDITIONS: +/// - Properties that should hold true after an action is executed. +/// - Implemented in the /hooks and /handlers folders. + +/// - There are two types of POSTCONDITIONS: + +/// - GLOBAL POSTCONDITIONS (GPOST): +/// - Properties that should always hold true after any action is executed. +/// - Checked in the `_checkPostConditions` function within the HookAggregator contract. + +/// - HANDLER-SPECIFIC POSTCONDITIONS (HSPOST): +/// - Properties that should hold true after a specific action is executed in a specific context. +/// - Implemented within each handler function, under the HANDLER-SPECIFIC POSTCONDITIONS section. + +/// - ERC4626 PROPERTIES: +/// - Properties that should always hold true in the system, which check compliance with the ERC4626 standard. +/// - Implemented across the testing suite as invariants, postconditions and specific custom handlers. + +/// - NON REVERT (NR): +/// - Properties that assert a specific function should never revert, or only revert under +/// certain defined conditions. +} diff --git a/test/enigma-dark-invariants/Tester.t.sol b/test/enigma-dark-invariants/Tester.t.sol new file mode 100644 index 0000000..b015666 --- /dev/null +++ b/test/enigma-dark-invariants/Tester.t.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {Invariants} from "./Invariants.t.sol"; +import {Setup} from "./Setup.t.sol"; + +/// @title Tester +/// @notice Entry point for invariant testing, inherits all contracts, invariants & handler +/// @dev Mono contract that contains all the testing logic +contract Tester is Invariants, Setup { + constructor() payable { + // Deploy protocol contracts and protocol actors + setUp(); + } + + /// @dev Foundry compatibility faster setup debugging + function setUp() internal { + // Deploy protocol contracts and protocol actors + _setUp(); + + // Initialize handler contracts + _setUpHandlers(); + + // Initialize the actor to the first user + _setUpHooks(); + } +} diff --git a/test/enigma-dark-invariants/_config/echidna_config.yaml b/test/enigma-dark-invariants/_config/echidna_config.yaml new file mode 100644 index 0000000..d7276b0 --- /dev/null +++ b/test/enigma-dark-invariants/_config/echidna_config.yaml @@ -0,0 +1,59 @@ +#codeSize max code size for deployed contratcs (default 24576, per EIP-170) +codeSize: 224576 + +#whether ot not to use the multi-abi mode of testing +#it’s not working for us, see: https://github.com/crytic/echidna/issues/547 +#multi-abi: true + +#balanceAddr is default balance for addresses +balanceAddr: 0xffffffffffffffffffffffff +#balanceContract overrides balanceAddr for the contract address (2^128 = ~3e38) +balanceContract: 0xffffffffffffffffffffffffffffffffffffffffffffffff + +#testLimit is the number of test sequences to run +testLimit: 20000000 + +#seqLen defines how many transactions are in a test sequence +seqLen: 300 + +#shrinkLimit determines how much effort is spent shrinking failing sequences +shrinkLimit: 2500 + +#propMaxGas defines gas cost at which a property fails +propMaxGas: 1000000000 + +#testMaxGas is a gas limit; does not cause failure, but terminates sequence +testMaxGas: 1000000000 + +# list of methods to filter +#filterFunctions: ["openCdpExt"] +# by default, blacklist methods in filterFunctions +#filterBlacklist: false + +#stopOnFail makes echidna terminate as soon as any property fails and has been shrunk +stopOnFail: false + +#coverage controls coverage guided testing +coverage: true + +# list of file formats to save coverage reports in; default is all possible formats +coverageFormats: ["lcov", "html"] + +#directory to save the corpus; by default is disabled +corpusDir: "test/invariants/_corpus/echidna/default/_data/corpus" +# constants for corpus mutations (for experimentation only) +#mutConsts: [100, 1, 1] + +#remappings +cryticArgs: ["--solc-remaps", "@crytic/properties/=lib/properties/ forge-std/=lib/forge-std/src/ ds-test/=lib/forge-std/lib/ds-test/src/ openzeppelin/=lib/openzeppelin-contracts/contracts/", "--compile-libraries=(Pretty,0xf01),(Strings,0xf02)"] + +deployContracts: [["0xf01", "Pretty"], ["0xf02", "Strings"]] + +# maximum value to send to payable functions +maxValue: 100000000000000000000000 # 100000 eth + +#quiet produces (much) less verbose output +quiet: false + +# concurrent workers +workers: 10 diff --git a/test/enigma-dark-invariants/_config/echidna_config_ci.yaml b/test/enigma-dark-invariants/_config/echidna_config_ci.yaml new file mode 100644 index 0000000..e73a2bb --- /dev/null +++ b/test/enigma-dark-invariants/_config/echidna_config_ci.yaml @@ -0,0 +1,59 @@ +#codeSize max code size for deployed contratcs (default 24576, per EIP-170) +codeSize: 224576 + +#whether ot not to use the multi-abi mode of testing +#it’s not working for us, see: https://github.com/crytic/echidna/issues/547 +#multi-abi: true + +#balanceAddr is default balance for addresses +balanceAddr: 0x1000000000000000000000000 +#balanceContract overrides balanceAddr for the contract address (2^128 = ~3e38) +balanceContract: 0x1000000000000000000000000000000000000000000000000 + +#testLimit is the number of test sequences to run +testLimit: 40000 + +#seqLen defines how many transactions are in a test sequence +seqLen: 200 + +#shrinkLimit determines how much effort is spent shrinking failing sequences +shrinkLimit: 1500 + +#propMaxGas defines gas cost at which a property fails +propMaxGas: 1000000000 + +#testMaxGas is a gas limit; does not cause failure, but terminates sequence +testMaxGas: 1000000000 + +# list of methods to filter +#filterFunctions: ["openCdpExt"] +# by default, blacklist methods in filterFunctions +#filterBlacklist: false + +#stopOnFail makes echidna terminate as soon as any property fails and has been shrunk +stopOnFail: false + +#coverage controls coverage guided testing +coverage: true + +# list of file formats to save coverage reports in; default is all possible formats +coverageFormats: [ "lcov", "html" ] + +#directory to save the corpus; by default is disabled +corpusDir: "corpus" +# constants for corpus mutations (for experimentation only) +#mutConsts: [100, 1, 1] + +#remappings +cryticArgs: [ "--solc-remaps", "@crytic/properties/=lib/properties/ forge-std/=lib/forge-std/src/ ds-test/=lib/forge-std/lib/ds-test/src/ openzeppelin/=lib/openzeppelin-contracts/contracts/", "--compile-libraries=(Pretty,0xf01),(Strings,0xf02)" ] + +deployContracts: [ [ "0xf01", "Pretty" ], [ "0xf02", "Strings" ] ] + +# maximum value to send to payable functions +maxValue: 1e+23 # 100000 eth + +#quiet produces (much) less verbose output +quiet: false + +# concurrent workers +workers: 10 diff --git a/test/enigma-dark-invariants/base/BaseHandler.t.sol b/test/enigma-dark-invariants/base/BaseHandler.t.sol new file mode 100644 index 0000000..f20e1f8 --- /dev/null +++ b/test/enigma-dark-invariants/base/BaseHandler.t.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Interfaces + +// Libraries +import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import {TestERC20} from "../utils/mocks/TestERC20.sol"; +import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; + +// Contracts +import {Actor} from "../utils/Actor.sol"; +import {HookAggregator} from "../hooks/HookAggregator.t.sol"; + +/// @title BaseHandler +/// @notice Contains common logic for all handlers +/// @dev inherits all suite assertions since per action assertions are implmenteds in the handlers +contract BaseHandler is HookAggregator { + using EnumerableSet for EnumerableSet.UintSet; + + /////////////////////////////////////////////////////////////////////////////////////////////// + // SHARED VARAIBLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + // ERC4626 + + /// @notice Track of the total amount borrowed + uint256 internal ghost_totalBorrowed; + + /// @notice Track of the total amount borrowed per user + mapping(address => uint256) internal ghost_owedAmountPerUser; + + /// @notice Track the enabled collaterals per user + mapping(address => EnumerableSet.AddressSet) internal ghost_accountCollaterals; + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HELPERS: RANDOM GETTERS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @notice Get a random asset address + function _getRandomBaseAsset(uint256 _i) internal view returns (address) { + uint256 _assetIndex = _i % baseAssets.length; + return baseAssets[_assetIndex]; + } + + /// @notice Get a random actor proxy address + function _getRandomActor(uint256 _i) internal view returns (address) { + uint256 _actorIndex = _i % NUMBER_OF_ACTORS; + return actorAddresses[_actorIndex]; + } + + /// @notice Get a random vault address + function _getRandomVault(uint8 i) internal view returns (address) { + uint256 _vaultIndex = i % vaults.length; + return vaults[_vaultIndex]; + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HELPERS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @notice Helper function to randomize a uint256 seed with a string salt + function _randomize(uint256 seed, string memory salt) internal pure returns (uint256) { + return uint256(keccak256(abi.encodePacked(seed, salt))); + } + + /// @notice Helper function to get a random value + function _getRandomValue(uint256 modulus) internal view returns (uint256) { + uint256 randomNumber = uint256(keccak256(abi.encode(block.timestamp, block.prevrandao, msg.sender))); + return randomNumber % modulus; // Adjust the modulus to the desired range + } + + /// @notice Helper function to mint an amount of tokens to an address + function _mint(address token, address receiver, uint256 amount) internal { + TestERC20(token).mint(receiver, amount); + } + + /// @notice Helper function to mint an amount of tokens to an address and approve them to a spender + /// @param token Address of the token to mint + /// @param owner Address of the new owner of the tokens + /// @param spender Address of the spender to approve the tokens to + /// @param amount Amount of tokens to mint and approve + function _mintAndApprove(address token, address owner, address spender, uint256 amount) internal { + _mint(token, owner, amount); + _approve(token, owner, spender, amount); + } +} diff --git a/test/enigma-dark-invariants/base/BaseHooks.t.sol b/test/enigma-dark-invariants/base/BaseHooks.t.sol new file mode 100644 index 0000000..5514f06 --- /dev/null +++ b/test/enigma-dark-invariants/base/BaseHooks.t.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Contracts +import {ProtocolAssertions} from "./ProtocolAssertions.t.sol"; + +// Test Contracts +import {SpecAggregator} from "../SpecAggregator.t.sol"; + +/// @title BaseHooks +/// @notice Contains common logic for all hooks +/// @dev inherits all suite assertions since per-action assertions are implemented in the handlers +/// @dev inherits SpecAggregator +contract BaseHooks is ProtocolAssertions, SpecAggregator {} diff --git a/test/enigma-dark-invariants/base/BaseStorage.t.sol b/test/enigma-dark-invariants/base/BaseStorage.t.sol new file mode 100644 index 0000000..4da7d9a --- /dev/null +++ b/test/enigma-dark-invariants/base/BaseStorage.t.sol @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Libraries + +// Contracts +import {EthereumVaultConnector} from "ethereum-vault-connector/EthereumVaultConnector.sol"; +import {GenericFactory} from "evk/GenericFactory/GenericFactory.sol"; +import {ProtocolConfig} from "evk/ProtocolConfig/ProtocolConfig.sol"; + +// Interfaces +import {IEVault} from "evk/EVault/IEVault.sol"; +import {IMaglevBase} from "src/interfaces/IMaglevBase.sol"; + +// Mock Contracts +import {TestERC20} from "test/enigma-dark-invariants/utils/mocks/TestERC20.sol"; +import {MockPriceOracle} from "../utils/mocks/MockPriceOracle.sol"; + +// Utils +import {Actor} from "../utils/Actor.sol"; + +/// @notice BaseStorage contract for all test contracts, works in tandem with BaseTest +abstract contract BaseStorage { + /////////////////////////////////////////////////////////////////////////////////////////////// + // CONSTANTS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + uint256 constant MAX_TOKEN_AMOUNT = 1e29; + + uint256 constant ONE_DAY = 1 days; + uint256 constant ONE_MONTH = ONE_YEAR / 12; + uint256 constant ONE_YEAR = 365 days; + + uint256 internal constant NUMBER_OF_ACTORS = 3; + uint256 internal constant INITIAL_ETH_BALANCE = 1e26; + uint256 internal constant INITIAL_COLL_BALANCE = 1e21; + + address internal constant unitOfAccount = address(1); + + /////////////////////////////////////////////////////////////////////////////////////////////// + // ACTORS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @notice Stores the actor during a handler call + Actor internal actor; + + /// @notice Mapping of fuzzer user addresses to actors + mapping(address => Actor) internal actors; + + /// @notice Array of all actor addresses + address[] internal actorAddresses; + + /// @notice The address that is targeted when executing an action + address internal targetActor; + + /// @notice The account that owns the maglev liqudity + address internal maglevLp; + + address internal feeRecipient; + + /////////////////////////////////////////////////////////////////////////////////////////////// + // SUITE STORAGE // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @notice Generic factory + GenericFactory factory; + + /// @notice System vaults + IEVault eTST; + IEVault eTST2; + + /// @notice Mock assets + TestERC20 assetTST; + TestERC20 assetTST2; + + /// @notice Maglev contract + /* ___________________________________________ + ________ ______________________>__ + []_[]||[| |]||[]_[]_[]|||[]_[]_[]||[| + ===~-~==/_\==~-~======~-~======~-~==/______ + ::::::::::::::::::::::::::::::::::::::::::: + */ + IMaglevBase maglev; + + /// @notice Extra contracts + MockPriceOracle oracle; + ProtocolConfig protocolConfig; + address balanceTracker; + address sequenceRegistry; + + /////////////////////////////////////////////////////////////////////////////////////////////// + // EXTRA VARIABLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @notice Array of base assets for the suite + address[] internal baseAssets; + + /// @notice Array of vaults for the suite + address[] internal vaults; + + /// @notice Evc contract + EthereumVaultConnector evc; + + /// @notice Permit2 contract + address permit2; + + /////////////////////////////////////////////////////////////////////////////////////////////// + // STRUCTS // + /////////////////////////////////////////////////////////////////////////////////////////////// +} diff --git a/test/enigma-dark-invariants/base/BaseTest.t.sol b/test/enigma-dark-invariants/base/BaseTest.t.sol new file mode 100644 index 0000000..2d08e38 --- /dev/null +++ b/test/enigma-dark-invariants/base/BaseTest.t.sol @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Interfaces +import {IERC20} from "openzeppelin-contracts/interfaces/IERC20.sol"; + +// Libraries +import {Vm} from "forge-std/Base.sol"; +import {StdUtils} from "forge-std/StdUtils.sol"; + +// Utils +import {Actor} from "../utils/Actor.sol"; +import {PropertiesConstants} from "../utils/PropertiesConstants.sol"; +import {StdAsserts} from "../utils/StdAsserts.sol"; + +// Base +import {BaseStorage} from "./BaseStorage.t.sol"; + +import "forge-std/console.sol"; + +/// @notice Base contract for all test contracts extends BaseStorage +/// @dev Provides setup modifier and cheat code setup +/// @dev inherits Storage, Testing constants assertions and utils needed for testing +abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdUtils { + bool internal IS_TEST = true; + + /////////////////////////////////////////////////////////////////////////////////////////////// + // ACTOR PROXY MECHANISM // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @dev Actor proxy mechanism + modifier setup() virtual { + actor = actors[msg.sender]; + targetActor = address(actor); + _; + actor = Actor(payable(address(0))); + targetActor = address(0); + } + + /// @dev Solves medusa backward time warp issue + modifier monotonicTimestamp() virtual { + // Implement monotonic timestamp if needed + _; + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // STRUCTS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // CHEAT CODE SETUP // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @dev Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. + address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); + + /// @dev Virtual machine instance + Vm internal constant vm = Vm(VM_ADDRESS); + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HELPERS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function _setTargetActor(address user) internal { + targetActor = user; + } + + /// @notice Get a random address + function _makeAddr(string memory name) internal pure returns (address addr) { + uint256 privateKey = uint256(keccak256(abi.encodePacked(name))); + addr = vm.addr(privateKey); + } + + /// @notice Helper function to deploy a contract from bytecode + function deployFromBytecode(bytes memory bytecode) internal returns (address child) { + assembly { + child := create(0, add(bytecode, 0x20), mload(bytecode)) + } + } + + /// @notice Helper function to approve an amount of tokens to a spender, a proxy Actor + function _approve(address token, Actor actor_, address spender, uint256 amount) internal { + bool success; + bytes memory returnData; + (success, returnData) = actor_.proxy(token, abi.encodeWithSelector(0x095ea7b3, spender, amount)); + require(success, string(returnData)); + } + + /// @notice Helper function to safely approve an amount of tokens to a spender + + function _approve(address token, address owner, address spender, uint256 amount) internal { + vm.prank(owner); + _safeApprove(token, spender, 0); + vm.prank(owner); + _safeApprove(token, spender, amount); + } + + /// @notice Helper function to safely approve an amount of tokens to a spender + /// @dev This function is used to revert on failed approvals + function _safeApprove(address token, address spender, uint256 amount) internal { + (bool success, bytes memory retdata) = + token.call(abi.encodeWithSelector(IERC20.approve.selector, spender, amount)); + assert(success); + if (retdata.length > 0) assert(abi.decode(retdata, (bool))); + } +} diff --git a/test/enigma-dark-invariants/base/ProtocolAssertions.t.sol b/test/enigma-dark-invariants/base/ProtocolAssertions.t.sol new file mode 100644 index 0000000..355bdfe --- /dev/null +++ b/test/enigma-dark-invariants/base/ProtocolAssertions.t.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Base +import {BaseTest} from "./BaseTest.t.sol"; +import {StdAsserts} from "../utils/StdAsserts.sol"; + +/// @title ProtocolAssertions +/// @notice Helper contract for protocol specific assertions +contract ProtocolAssertions is StdAsserts, BaseTest {} diff --git a/test/enigma-dark-invariants/docs/internal-docs.md b/test/enigma-dark-invariants/docs/internal-docs.md new file mode 100644 index 0000000..5a022a1 --- /dev/null +++ b/test/enigma-dark-invariants/docs/internal-docs.md @@ -0,0 +1,292 @@ +# Internal Documentation for the Euler Earn Enigma Dark Invariant Testing Suite + +## Table of Contents + +1. [Running the Suite](#running-the-suite) + + - Prerequisites + - Starting the Suite + - Configurations + +2. [Property Formats](#property-formats) + + - Invariants + - Postconditions + - Global Postconditions (GPOST) + - Handler-Specific Postconditions (HSPOST) + +3. [Handlers: Adding Support for New Functions](#handlers-adding-support-for-new-functions) + + - Overview + - Adding New Functions + - Testing New Functions + +4. [Debugging Broken Properties](#debugging-broken-properties) + - Logging & Output + - Crytic to Foundry Test Helper + - Steps to Reproduce an Echidna Error Inside the Foundry Wrapper + +## Running the Suite + +- **Prerequisites**: + + - Ensure that all protocol dependencies have been installed: + + ```sh + cp .env.example .env + + forge install + ``` + + - Make sure the latest version of **Echidna** is installed. If it is not installed, you can follow the guide [HERE](https://github.com/crytic/echidna?tab=readme-ov-file#installation) to install it. + +
+ +- **Starting the Suite**: The suite is able to check the invariants and postconditions of the Euler Earn protocol. For that it uses two different modes, property mode and assertion mode respectively. + + - **Property Mode**: Checks protocol invariants. Run with: + ```sh + make echidna + ``` + - **Assertion Mode**: Checks protocol postconditions. Run with: + + ```sh + make echidna-assert + ``` + + - **Extra**: Run the suites without checking for properties, only increasing corpus size and coverage. Run with: + ```sh + make echidna-explore + ``` + +
+ +- **Configurations**: The suite configuration can be found in the [echidna_config.yaml](../_config/echidna_config.yaml) file. This file contains the configuration for the Echidna testing tool, the following are the most important parameters of the configuration: + + - **seqLen**: Defines the number of calls in each test sequence. + - **maxDepth**: Sets the total number of test sequences to execute. + - **coverage**: Enables coverage tracking, stored in the directory specified by `corpusDir`. + - **corpusDir**: Directory for saving coverage data. In this suite, coverage is saved in `tests/invariants/_corpus/echidna/default/_data/corpus`. + - **workers**: Sets the number of parallel threads for Echidna, ideally close to the machine's CPU thread count for optimal performance. +
+ +## Property Formats + +As mentioned on the public documentation this suite framework spins around to types of properties, **invariants** and **postconditions**. The following section will provide a detailed explanation of each type of property and how they are implemented. + +### Invariants + +- **Definition**: Invariants are properties that must hold true across all states of the system. These are checked when the tool runs under property-mode, making echidna call all public functions starting with `echidna_` and making sure the assertions in those do not fail. These checks happen in between every call inside test sequences. +- **Example**: BASE_INVARIANT_A + + - **Spec**: totalAssetsDeposited + interestLeft >= totalAllocated. + - **Implementation**: `BaseInvariants::assert_INV_ASSETS_A` + + ```solidity + function assert_INV_ASSETS_A() internal { + (,, uint168 interestLeft) = eulerEulerEarnVault.getEulerEarnSavingRate(); + + uint256 totalAssetsDeposited = eulerEulerEarnVault.totalAssetsDeposited(); + + if (eulerEulerEarnVault.totalAssetsAllocatable() - totalAssetsDeposited - interestLeft == 0) { + assertGe(totalAssetsDeposited + interestLeft, eulerEulerEarnVault.totalAllocated(), INV_ASSETS_A); + } + } + ``` + + Every implementation of an invariant must be called inside its wrapper `echidna_**` function on the `Invariants.sol` file, as shown in the following code snippet: + + ```solidity + function echidna_INV_ASSETS_INVARIANTS() public returns (bool) { + assert_INV_ASSETS_A(); + assert_INV_ASSETS_D(); + + uint256 sumStrategiesAllocated; + for (uint256 i; i < strategies.length; i++) { /// <--- Looping through all strategies tokens, + IEulerEarn.Strategy memory strategy = eulerEulerEarnVault.getStrategy(strategies[i]); + if (strategy.status == IEulerEarn.StrategyStatus.Active) { + sumStrategiesAllocated += eulerEulerEarnVault.getStrategy(strategies[i]).allocated; + } + } + + assert_INV_ASSETS_B(sumStrategiesAllocated); + return true; + } + ``` + +- **Implementation Guide**: + - Define core properties of the protocol (e.g., balance constraints, liquidity checks, internal accounting accuracy). + - Keep assertions clear and straightforward. If looping through users, assets, or reserves, aim for simplicity—avoid excessive or complex logic to maintain efficiency and readability (check example above looping through the suite actors). + - Minimize redundancy by ensuring invariants don’t overlap too heavily with each other. However, certain degree of overlap can be beneficial for covering more scenarios, so consider strategic overlaps to maximize checks coverage. + +### Postconditions + +- **Definition**: Postconditions are properties that must hold true following specific actions or interactions within a test sequence. They help ensure that each action in the sequence produces a valid protocol state, focusing on targeted outcomes rather than overall system-wide conditions. Unlike invariants, which are checked consistently across states, postconditions are enforced at designated points. These points include the end of each handler call (for handler-specific postconditions) or at the end of the `_after` hook (for global postconditions), validating the expected results of specific actions. + + As the public documentation states, these checks are performed in assertion-mode, where echidna report a failing alert after detecting a `Panic(1)` error coming from a failed `assert` statement. + +- **Categories**: These postconditions can fall into two categories, the global postconditions and the handler-specific postconditions. The global postconditions (GPOST) are checked at the end of each test sequence using the `_after` hook, while the handler-specific postconditions (HSPOST) are checked at the end of specific handler calls. + +- **Example GPOST**: GPOST_BASE_A + + - **Spec**: lastHarvestTimestamp increases monotonically. + - **Implementation**: `DefaultBeforeAfterHooks::assert_GPOST_BASE_A` + + ```solidity + function assert_GPOST_BASE_A() internal { + assertGe(defaultVarsAfter.lastHarvestTimestamp, defaultVarsBefore.lastHarvestTimestamp, GPOST_BASE_A); + } + ``` + + Every global postcondition must be called at the end of the `_after` hook in the `_checkPostConditions` function, as shown in the following code snippet: + + ```solidity + function _checkPostConditions() internal { + // Implement post conditions here + ... + + // BASE + assert_GPOST_BASE_A(); /// <--- Global postcondition execution + + ... + } + ``` + +- **Example HSPOST**: HSPOST_USER_A + + - **Spec**: After a deposit or mint, the amount should be credited to the cash reserve. + - **Implementation**: At the end of the `deposit` handler, the postcondition is checked. + + ```solidity + function deposit(uint8 i) external setup { + bool success; + bytes memory returnData; + + ... /// <--- variable caching, actor-call, etc. summarized for brevity + + if (success) { + _after(); + + // POST-CONDITIONS + /// @dev HSPOST_USER_A + assertEq(defaultVarsBefore.balance + assets, defaultVarsAfter.balance, HSPOST_USER_A); + } + } + ``` + +- **Implementation Guide**: + - Identify key outcomes or state changes that should result from each action (e.g., balance updates, collateral adjustments, interest accruals). + - Aim to complement invariants with global postconditions, ensuring that properties that are not possible to be implemented as invariants are still covered. +
+ +## Handlers: Adding Support for New Functions + +- **Overview**: As the public documentation states, handlers act as a kind of middleware layer between the tooling and the protocol. That is why when new features are added to the protocol or this one is upgraded, new handler functions must be either added or updated to support the new features. The following section will provide a detailed explanation of how to add support for new functions in handlers. +- **Adding New Functions**: Let's take the example of an upgrade. The following steps show a guide through the process of adding support for these new functions in the handlers: + + - **Identify the Handler**: Determine which handler contract will be responsible for the new functions. + + - **Identify the parameters**: Determine which parameters are needed for the actions, which ones can be randomized, which ones should be clamped and which ones should be taken from a finite set like a helper storage array. + + - **Identify if the action is permissioned or permissionless**: If the action is permissioned, using actors as proxy is not needed since the suite is setup as the owner so a direct call to the handler is enough. If the action is permissionless, an actor-proxied call must be used along with the `setup` actor selection modifier. The following code is how the `deposit` implementation would look like: + + - Function should be called by an actor so the `setup` modifier and a proxied call to the protocol are used. + - The function should be called between the `_before` and `_after` hooks to ensure values are cached for postconditions to be checked properly. + + ```solidity + function deposit( + uint256 assets, + uint8 i + ) external setup { + bool success; /// <--- Variables to store the success of the call and return data + bytes memory returnData; + + address receiver = _getRandomActor(i); /// <--- Random receiver actor selection + + _before(); /// <--- Before hook + (success, returnData) = actor.proxy(target, /// <--- Proxied call to the protocol + abi.encodeWithSelector( + IERC4626.deposit.selector, + assets, + receiver + )); + + if (success) { + _after(); /// <--- After hook on success + ... + } + + } + ``` + + - **Update Postconditions**: If the new functions introduce changes to the protocol state, update the postconditions to reflect these changes. +
+ +- **Testing**: After adding the new handler functions and updating the postconditions, run the tooling to make sure the new logic is being covered and work correctly. You can check for html coverage reports inside `echidna/default/_data/corpus` directory. +
+ +## Debugging Broken Properties + +- **Logging & Output**: While running, Echidna displays a terminal UI that reports the status of properties—either passing or failing—along with relevant call traces. When a property fails, some threads initiate a "shrinking" process to simplify the call trace, making debugging easier. The amount of shrinking effort can be adjusted in the `echidna_config.yaml` file using the `shrinkLimit` parameter. + After shrinking completes for a failing property, the suite can be stopped with `Ctrl+C`. Corpus and coverage data are saved automatically, and the dashboard's information is output to the command line, allowing to copy the minimized call trace for further debugging with Foundry wrapper tests. + +- **Crytic to foundry test helper**: `CryticToFoundry` file serves as a call trace reproducer where call traces from echidna output can be debugged easily. The following is an example of how to use the helper for a failing property: + + ```solidity + function test_INV_ASSETS_INVARIANTS_1() public { + Tester.donateUnderlying(1 ether, 0); + Tester.simulateYieldAccrual(1 ether, 0); + Tester.addStrategy(1, 0); + Tester.toggleStrategyEmergencyStatus(0); + Tester.toggleStrategyEmergencyStatus(0); + _delay(2 weeks); + console.log(block.timestamp); + echidna_INV_ASSETS_INVARIANTS(); + } + ``` + +- **Steps to reproduce an Echidna error inside the Foundry wrapper**: + - Copy the call trace from the Echidna output. + - Initiate the `[echidna-trace-parser](https://github.com/Enigma-Dark/echidna-trace-parser)` tool. + - Paste the call trace into the tool. + - Hit enter to generate the Foundry wrapper test. + - Copy the generated test and paste it into the `CryticToFoundry` file. + - Run the test and debug the failing property using foundry verbose output `-vvvv`. + +## CI Setup + +- **Overview**: The suite is integrated into the CI pipeline of the protocol to ensure that the properties are checked consistently with every updates. Once the suite has been tuned to be fast and efficient, it can be integrated in the development cycle to catch bugs. Once optimized for speed and efficiency, the suite can be incorporated into the development lifecycle to identify bugs early. The following rules should be followed to configure the CI pipeline for effective integration of the suite: + + 1. **Corpus Directory Management**: + After completing the invariant testing engagement, a `corpus` directory is generated with the coverage data and reproducers. This directory represents hundreds of CPU hours of refinement and is valuable to make the tool run efficiently. Since an attacker could use the contents of this directory to quickly identify attack vectors and vulnerable code it is excluded from the files pushed to the github repository. The `corpus` directory is independetly stored in a private repository, and the CI pipeline has permissions and is configured to pull from the private repository to get the `corpus` directory and run the suite with the coverage data. + 2. **Ongoing Fuzzing Campaigns**: + For every code update, new feature, or public release, the fuzzing campaign should execute for at least 24 hours, starting with the existing `corpus` directory. This process ensures the corpus remains up to date with recent changes and verifies the suite continues to validate critical properties. + 3. **Corpus Updates**: + After the fuzzing campaign, the updated corpus directory should be pushed back to the private repository, maintaining a continuously evolving corpus. + + > Note: The CI pipeline for the public repository is configured to pull the corpus directory securely from the private repository, which requires proper permissions and secrets. + +- **Setup**: Follow these steps to set up CI pipeline permissions and integrate the fuzzing suite effectively: + + 1. **Create a private repository**: + - Name the repository following this convention: `protocol-name-suite-corpus` (e.g., `euler-earn-suite-corpus`). + - This repository should be owned by the same organization as the public repository. + 2. **Initialize the corpus repository**: + - Navigate to the local `corpus` directory, initialize a git repository, add the remote origin and push the contents to the private repository. + 3. **Generate SSH Keys**: + - Create a new RSA key pair: + ```sh + ssh-keygen -t rsa -b 4096 -C " + ``` + - Add the public key as a read-only deployment key in the private repository, using the variable name `DEPLOY_CORPUS_KEY`. + - Save the private key as a GitHub Actions secret in the public repository under the name `SSH_CORPUS_PRIVATE_KEY`. + +- **CI Job Overview**: + The `enigma-invariants.yml` job has been configured to pull the corpus directory from the private repository and run the suite efficiently with the coverage data. Additionally, a new configuration file, `echidna_config_ci.yaml`, has been derived from the suite's original `echidna_config.yaml`. This CI-specific configuration has been optimized to utilize the `corpus` directory and coverage data efficiently while reducing execution time. + + The adjustments include a more moderate number of runs and sequence lengths to improve the suite's performance in the CI pipeline. Since the primary goal in this context is to validate against existing coverage, the suite can afford shorter execution durations and reduced sequence complexity. + + - `testLimit` reduced to 50000 + - `seqLen` reduced to 200 + - `shrinkLimit` reduced to 1500 + - `corpusDir` set to the `corpus` directory created when cloning the private repository. diff --git a/test/enigma-dark-invariants/docs/invariant-suite-inheritance.png b/test/enigma-dark-invariants/docs/invariant-suite-inheritance.png new file mode 100644 index 0000000000000000000000000000000000000000..0fea1c331e14e9ba23beffeabbfcaecf53eddc86 GIT binary patch literal 480992 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%0A+?u$I+bsq?u?aL z-^Pc}r31|k#lm}=Z^7Wi&#LCOziQM%f}!xEK{u%M)XilO@~O4vytCStal6|%On0(5?a z>OGLkT5LRDR3h3T?K10EZBYz~>my)}7!&)6(i`Bw=C`&ihPdx(+3wDZI{^wZln*(~ zBf1+rvu6}sLbn-4L9nu@wY62;eiN7>3O80I=@tBY0+z)gtZ&9z?6ZKQ%6zNv z?WK6m7W!>(Kv?khb}j|<^vIv0{tb)>!v%#AL01CTPfaO;YfHQS{3gFx*MIy}9M6-X z<~(fZt47A9cg`(BF8d&4ENb1Jz`Pk#mT?f!zOP3Z3r2(PV$j|-Fjcw__2e?Q=0NyG z#Y+zPxldHfhBe!RifA^HFQ6paW2RX(`?X}U?+$6^X+D)|*juosASlM9`((P#t6>Jo zoLgpVvdXyD17?0^MsNScqQnD00V97jS8#rQ9;9s~;n&b01Wh}Bmf489z5uLE!Ym?#rsczHt61c3#PG@fHzMSTK@GXj2hrS3s)@lP;sZd zRy;jD!z7R;(2}RBU1I_LE!m4?%|>6a$^r<{r!<|T&7a1b6J16?G9E!#lTB11nq;b~s_~EsKRArBL2PEOU4a9) zi_`aBhZGVKa+UUO?e4a=%q+lDeaG;r_B^&c-~3rINJ7Hn6ag~o)Z=Oi&JQGf38kyP zhT|0u48RoY0CFb%gOEsG#qT4j8M29e?=h)_NQLQbQ!V06hjNoa)R4osc<`FfR3fP8 zEbYse_m=g57esG+SG&qd9=uzYda=pk#O+~z{)hMR@o6tVgqeb63_b5W^nnq?QcQmI zH$vz+K?5D$m{83{zL7xDT0lG{ARvH+fuYaW5^ek)X?>zB9H?4uH5}7%zY|q|+?zSuQU%xrK;USy>r$$Wj8Q z>OT#4k=>-sURhPuNhGtx38}4%WM>{v6Au>>hDU|5^np{3<#A@MI@_$cy%mq`{IYGf zc(^t>x+|V5mdSgvx>Ds*TPmJY86)mvg~wxkK-Wu^f(%Su2h{s&a%g4%lLwb@=U+X; zAFFVVnjjhEzPzP-axI*p8?a!gtHuqB9}M>xjcZ<PZ$1mWh1~5Bjq0rNzV;M-r!6y6Z4ZRTZXVznhJQ zz17M#1SG)LkxWqD1i%9t0T_AJzrDNz{EMush1+c~Yi!u_@bOX0G9|`)6BNy2fx%qm z0)f5BtgNh*as+4N&B%#!_LucA$>29>Kl7df=>o??jP(CDjRPTJe{g-#O};Shdh_G=q?Td8{}`IUaDyQDqVTKs=$6iq?&EzDK|+g%P&=vx2QN`l+DN zdYR2q9|*Q{juNb~$$`2)ck$2}WM{0ayYnUZG5a=)i%yvYdd!^5<;fEB%a;3J1Rt+9 z&ro)r5p!631E-0lWtyp|sYwWyH_9-vs-BKiIOLT-gwOljsT_PYE|>3p_Nti}Pd($% z#x!utcl8nv4{z4F)OJOI({44Qj%RhGAQdUNw7gusGU@^87W6e74#$Qb3+LAj{dhp~ zH{mfqDlSMH{4DOL-;mgpX#)|`tZ8(#_xu$cnveNu-t(K9~c$}E0hZjJIUuXtDGV=H8rIY z9Kg)^1(-rliSab_7jh;=ePvmEPgGPie2dHhI*hPAQxD}=32ZWyL``2GE0$#HIz3pU z&<2g&AUF(Q^sfH&)0vztFZUkn>&e7=W)OEpczYHtsaDv(IR#mM7GRab*`T8D;sP+= ze0s@_jq24A&>Q2yY~|IfMOvKmCO64(5T6NS`vGz_JHkzR0K6nwE9Hk5#3(P1@lhwK~-q^?wH$&5W3 zBri_P^SO(w08kn!if0w>E-u_q+uo4;5!kb4vI^_U`$p$nV9D?snOT+lVmw_@SsW%+y$=;Ic6(H@2hel*stF?Yx99VKWDs;28 zKETGkjEgH34X2b2gSTYQ?afhTD7@&X3e9<8dEa*_^(VCP@P&Yv$5R+r&_}-h@aQPC zU}xKL5}0qYtxX;k)W1PMJR;zKkAd|3%9;3UMWEJul!$46Z!bKT7_?vU+$%F1(Q!NR z;XPY_c92~fR#)eRm?f9|Tt#E$;_L|E<7!OAHO2`!n9==RiF~p^f&0q#K|Bp*YiRB6 z@9WD12OYMG1pIk=S{k_tSoD#`p!#yU?H=LV>5};ze8i`vDITe*sT}<*Z##j^yipyB>GcZGz7 zdqD_j41$?&gVaj6CW!FXtHf3lZJo`B>Kbcdk>NfD%`K!l-}gm zvgB!k++KUscsviY?)Esr9O{3Hvi=RGx6TFeEr-1+PXTDD0OA)r-`P-+ zL|)ecz9p86lcmJjnv*0qKs<2z3_{Cj&~$Hgv@qi(A%vIF?fmVi@vf&E@4614h${3# zv!3yNB>EvVBqW4}nbVcac9~z(=lNjAS59zUASmli7W8`(6S6vsLcl5q#A?7`)G4GR zzQ`W?j$pTEm~;Lk)t>F$U5rS94r6HP5l~)eS!dCP8g#uarTqVBIm@Ou`p{Yxkk;}64%nzT{#E_fJlK#>e5WDG18EhoFU!vC`Y~TRi zEsM$>U!)h7kqErUyq44a;g9JoS^NPNq$1NfphwD7_#)AiZn(V%Si5>g3ylU{J9uvK zIqtqx2bj08%}gNQ@id&?{K^UqUi&BKm#t~PgJCCsVjd@IC++#o*5uo$9dYbd&t1-e zW$7=qnv+6hPfJe^sQqY|?+5o_Opj13_3q4Z174282P%@vMRId8)}6wrcoUm>#6!)UCmQXpr!X_p1I%f`VJ}3q^eX2gu>A=H3_B!{ zSzYmPuFCE?t4MDEWURWXoZJHW(3P}~>p`SUK;bUWSDtjlO_i zUeq--p*exw>LCg~b4%JA&1x5pojONF{H+y$JyD#!THY=K#j*%T(<3dAVbiJQ^IyyX z*YVz{Gp;F8p!B)F;oKIM9|6cwlBw_2PxoVXokZ|h%uB?OT38fx6*ZO!n15Cv8tdlR^^jsf4(S0&@HjY|R`P7dfUF!4mwc)%dFjP&E0EensM+O$BVPRuapw3OzxF-VcHPT7$#OP=- zpx6U|zkYXny9duNQQl2u0iOhaX-6`OUK+$uwkv%Uvl4eI>^J(>Mys41Vp!kcmz9>b z9L}&9tEf+x5pj}#t?nza&^ZOyb1>N4}@NF#U_K9!0yfi?Ba5J zW*?9nLhF?8>+d>jPW0lb7iN1?pkX?jK%(j&U!!p^4Gk$f6L@0TM|3lxRif3QuaYb# z14*>X+5SlZIXO8a6@YdphhZU`urgyznZ>M1Gyo?jBivpX4fUZVV^f^{<+d>7eolL^}FDuPTU-y)Y>D z|E|O-2@QU}5Cp!u4t_kepv4i@ai3OoQr#|s(_)L}NLWx`$ar>_w`U44(L;+22+z*9 z6i}JBV=qyP{r!#Hn2M5_qdeevtLMSo#v(BzCjE2ZIzB%WRYGJO0(-s?!AgR>fuE&g z4PbSLEj@@_a=aI07%n z9?xOZG_84j>oOzJO=A4}WE*+EIVj`kK&4@+y2_=Y8y64vpw34(6JkNesI`$_`jTM_3_oa!4k#P*CD_YLOQUT#Ag%SV=T~>mukOasQB#Ytjzs!>&bNI89V|irJJs}qs%Cv` z$d{XH&j)C=r`ZfpjiA7~Oef~B6Y{ym$p9VWsO+}*uvBu)W;zrU!)*LqTU(p5b9=ru zT;B|JR!B%l4obyT4XBuuvXy9%k&u#rLSs%f53mAw5^MpiI%RS@y965vsJQOc2q!+q z*w#1ztc6mbIH^RKB!?3H`Lj5Ho05TRgC-=@pfv+ZfC=i~vuKD905l^L^g=T)ZybBWSJzlsR}(wy-|0=2GGs z#P87uwk|C3)dBJ6Z~i>ahdqcSE=kqiZ&=MIGO5>7=6TmU0P&+_RKs3fwMy!W~~r^@&ao}n*}!)Bm=yv&B`FGFira)2AgC49X5w!2zw@z`2;((@P;&G zIT!#6y&A5GjHK}2B>3q^lE}9sl=tdg*98HNcs4@Sf$>*iiZuN1S~cMrNX%Hv*lzp$ z0xzfepd^NBMX%8Tq9s?Q1*EXm=hpj@X?K8A?1SRUDX6h#0Sn~#!3S;02K$z*tSmIp z>pgG>IcCZ`5s(UJfz=QqX9TO;({*t2WOD!rR!V-3fPQb<@inXS$Ro(ZAIg~4*8a^Y z!9N-uMWEKCaFA7t8d#Hs#_7MaCf}h^y|X(b*G*JU0NeE6Xcob3kQ<4F5CClufd^c} zEu*7&GWR|BS)ud^odlth<{`jvkBU8k`>Vs^fPQve_Andw$@6fpYC^{yex9xgg3-zJ2Y)wf`4j2CSQ1ahI-MBhe+7^{ z(1LDAg)hhN%sUCxgJHVgu|Uh?z7L!JY649+1GWiO0d(195Cq;-hJhP@aOQfhE6{JI z6>_L2T&Sth>#d*@B3pjDm>0)AKt#OaibjTmqsgR5ekA zgJ6FD#Xl)0Xub#{N&^jYGHf{gzSojmfzEFK?8BrwzM*9`2i?eh422 zbTvSLYPJ@uDgt`(^46J$eh-fQBaF{4Qmd9vR)MCV-~a1n%d~(5PgK{d{qks}7D&e@ zC*n8($g++GQ(wy@Kw&TIeZl`an*R*cj(i4kZU0>_n*REA=Q&{jL))~(X3;A({_hZt zv!sW#tS{H>rx$Nz&65y{fq$65sffV>e^;y({cGOm|G1bns5EKG2HoU*_ZgKz;~E#U zyK35GyS08k8I!`5i?kNs>2FyJ<$`zGUlstad9^V~UvP6|I9C&l7XLkAlHR|l=TiO) z1I}NMKk*0(;g3q@!ry3OXcR(`7fR-KL{#GKy&*6$?r2_mgYN$yr^gS0GGeKkJ;J$> z7kgl&y@)J`(|JSayhzMiAwQY85ur z>7#!fWMCeL6cn5&-V^S!j;i2#)(uOt&M^A(^O0k73VKI~pvV7SG!y#17NT3fFltrG z?VKRak}iJz8@piFL`$BLq14UqpR0nDAbXh>>`zhd+56K@keiQgQ3J0uxA>V8ENDW) zA`7iID!?QNP%{a*S>uEVwj;1pTVONbnq{VR29W<@*~QIw)EascvMR0;K|ks~^$SwJ zZv8snFx8~7>*W~ye6VZoI%-dF^jKpL_N*%IiOAk(^##OtiEs zoZvJDEqzWV->;7^Nd@eBQsrb0zgsqT~iD@&koXC8@_Jnma*9oGvtNx zbl`qH3jME@TKrh0)zzqbC+FzCm;|}O-+?5(X`GP#=a+Z~4>7;IqsrDEkL`N3?X<-6 z`x5#P6nMQdFwE4Za;Zl`CygAgH_dtC!w+3SwgCcQ2|5-9S4`HS_aZ8l_wZlO|KHw* z-yF7NiuebKyX#MmjqWX(A1i^W@keEzH_|PJDRzfdYGLnabCbS7kwArE>POs=kpntZ z9H3t)>wsaFnY?x}Og++5lg0Lbth^)e9MG-Li4vXZ9}hQMWs<)>9Y#CP2;F)m87U02 z=u;CWzMKCEsRdbB>YXPzf%j$KTBE-P3v7Et+OIb>|M_*OrAS#u?zbnjEw=qoPa=eV zQl`@M5#QCM`pLj^AJ!)-<#LhINzXk=$h?iPhrYgqJwry~-+a7OW(NZ%Z{Gd0Mn~RV zA5$CMc5!pSkkKJjhJ10ke$*Z<(uE@5_QE+!$HU4qU7jj|{A4Pzyc@CbxudD0<9Fh6 znVG#{{X#9W4G$P5J)~b-6#wlqem{Wj4_FIcHx!*s68kPtVJ57y`SI)WF|nZ+LMQju z&5d}Ljfrj8jP-6{qkhVdbm1Fmx<`>uY_{#-ojl)8Aex_CnUL-O`&0k3xP65;ui^3L zyF88A?-*cxK`A{ZeXTCK`aoSIWAvjLeev~6lgrH1<3>`Lt{23UGKSSU9q)i@!OZNe ze%j~*RwH0u;wp?bumAEte-HT4vbgT>?RLZHUx$?;U*&uKYy(uG7}RmIOB+u4WcKt4 zBlqD@e`!vVw&&d3oM_`+)`1F~auxc&a5~id)1A$EGwm0G3KTML#PqFijNJ&erQM!v zY55EDL0~Ws$Pb2UKEBA;3wy&vb0cxlwFd`w(cMcSO&atiS3E}ft$5U2;I-D(4S)O} zucbq}FrFGKuT#a1oH&`V&v(b-#+P9ut#eWs2V}4?zXAIQ8~VXH*8RGs0h;_v2e=HD zfil$7Z1wzP2Jx-`ZQlQ<`2p_d%{!C=sSMVa6K0B3Q2pzLSCBD{w$7h{Dkn-%PLv{n zh=$B<%4-ElMK(Ki_SCJ%QAYpguQ|jK`}wwv)5EfUa)KCo;hxCw3SM3u@!mylCW2;j)@8X#u@b+cniP+I z{9G?Vuqlo3`5@PIK=DVl3@xaQ4biEOI`dP(Mq(?PwSESD5GC@^)3TU)V-)G}xG}k2 zSQXmq$5X=`u~ql#k9`u(3s%>i%I%~6^EG3EkLm1Nqqxh4RfH7r9C~0?NNK+K)|_9H zJx6U#>aV?GE-n|tFL_L-%BLB)Z?rO>zH&g@jCY51euTy5M#lbh$+eyc3T*li*+KRyu>VK~C@bzQzBpQo}Iz};YHv) zr>@SO^Ijmctv4=`K|h;XEJ-?(Y^hs1mf)^>k;Kh|bHTI550MV&j_%U{-;t4i(x61mNBG9V&4<2(OqTIBjt8I55Cn#4;oGF$JkVhzePLc`KON)dmOyC-DEmpv7O z)%=iQEg1R@asjoxiIF?Dsj?Qb0i^7_ypw8vmV)RT%J9%37(_$ujdA7xose?UNH!|FHmxelLS!OHsJ zKdc8@AthJ_RfK!VX7{dN>yIyiMcSiUN~X}@Q4gvexTLAqYXdXoliHW`-wV{di6t>A z9PRcHJRkgJRHbxu$Cpm^3${P=Uf>vV2m+q;al^jrqy6JKJrGT5r|ilwBxG}d28_V7 z2P;O%-$eX(J?S%;8}uaZu`s)gvkEjh$4&O=CznNDpLr1JeObMj?j^Fz@|E2eyw4SB z@fGruQw$&9{P>S|Aw^!dPdt?Jxrrj!*O1= zY@A7z1>k~o6=1XYmJ}(8yomjf7;{62mI!4{GU*0-*g*t$HNp7Vx=}iO2jK8xWj}dt zZl;zPmPXHavG{4neOVJr^am0kw4*kj`{T`D|5cKu=L2*9SRn*NWQ(F*==GC|lltO= zL`A&3WIlGxn*iT$F*X@g{97LjUZ+8fY5cMLf^n+%n2!mGzX>)4K#dE`pO60fR`zK@ z5VccY{^Iado8i&*RdFBeLK1E+8g*lTe0=4$iM2Mm~p_b1D=$a3Xx1EsbJD?u($ zaNg4*`78U;LT0|dXRpi#r9$8U6w@J|%J1vjZUP(I7g9|L6#veR5@j900wsR`G3_?F zYyTtLmd-Q+dD16hfo1Q*FGut3({-j6vZ+-`9)HD1!b{`=I~?}`ucTz=a-^DlUu32y}l44yTtvlv`-l1y1P z#)SxXMf`t$d)`T@V^4s^x4|X{VSyXzQobt|oZYMmykh%Ie63r>!rpHW-{<-j?by4U zw|sj!@Kgd0mTN5YxCCXgCjYyzuyx__%?Ii@zlh4bcx+qCruAz^zv(641wV~t>)npt z|80El?B&akfmK(}=Ajg?z4yFVcT}`7rP|) zo#pv{cf4Alw&z_dfscjs00Pt3#|?Q z5=ryZuRXtMwq@h58u`cNrJsQVUhSeDH(%%n6x@)jux?xl3}v6C!q4yz^q>U67qttj z5*MG|tmS$k#Beix&%)QY)B9BICU5GrU-~Xq`fu>Pi`QcwMbz%oPJQ=I(P4oPuybeh zdzBXMh(s|SsaT)T3XB4=Tq94?wFWE$YMogdDvHZ&+_mZn;Lw3$x7kb;(zR*?1BZgn z>|51^S~?+l32N=ueG)bd48o5*T^vI&Wm6P^O%K=EJ_JTpu@!_B1A938pkqzb+q4GU6K z;~i!KwWfXx4aFAc*tNidOo1Di|8#DpOd?(DXx2rI1z3=xrHj$*N>uqgnqAS-4c2@+ znq9F53wqEIUDINkHkw@rS$18p`v9nW_-_42HiXOe0xS0~r(UL#UTZZtNCRs;v#58f zxZ8L*`#V*@x$+lNF9U~6a4Nwi)o2E+qjR_1@kURpM40piG|#WSd^+h(8AhgDU|Z%^ z#?I+DY9|~XX|w@%o}Lx%g#>*VOsP`F{Bv~M994XL-lNZPud;VXEmf+Qz53IbbxZb!^bNYVvXydoCZFZd?9 zpbn9~i4AIlMZoFrjvsCK2WPMb;a1?%h%5V;uHc{l#_Ah4V1r&l@csp2U5UtP3(9~A z;#PRWFVf@YKnE~xlpjgY!s;8mPPw87?DqWT3b4oO8(cXStXKj#eV^!3<4i_^xCKlQ zS@Ddo@DI^q^^G#Hcjil!|2GDX0;w?frTf!HZX-uk^NzXKlz&w5pYnC7oVg|E-1!2Y) z=(IZl#c06@T?1x(LhcjIfH^?lT4t31j#luvB^;s zQIMPj1Vkn0oZ+j3gHC*hANPLi-nHI8Gp@twbM~%XyXvW@o_+3LR+QaM&Op9p%a+|2 z&Pyq8*|O7e%NDX})ONVSU~tV2{zqc1EPHlKa`pa!En8T&T#!1W;-E9!vE#`h%!1&T z{6i!=Z?kfKCFQ8ofBM3DpVX~KyY`XoyzO!9%;htZw-259pz(<8gV24KM^9eRO5HBG zO?Ku&gzeNVYL%wKxm`>L&612{UfFFP7IK>y3Gy41rQ?pj4Y}hu z@4>-D`=ujE5r3bO2Qy6)v>VL z15}%uaV-gHspf&3sNl`mvNoTTN?DH0$$m+!(7KxtF76h3bThw`jMRp=j64$L+1!-H zxM9i-<(5;Mn=(;e(jifMviI=j#uC5HE8A&t-aPz|R{qyFdD_8pWy*IJ{OcWmn$t89 z%zufwxN4K;KTgt3u=^1DbaP_~r={#19Qc;)_@CYx`IziT%o7=#`rAp~TRhLuP@VL#4>37RqCbrvU7)Op=Z#o3lM7 zW#{Cce;?!NZ%Jq*r#q)=iGW=nl95W9_}MC&*^GJ2pG)x0%(IqyWFf z`V1(M2`fmxNN!Mk>-47)|8sO)qk>5b{9m7RZR~m^$g>#JNa2T>f3>jZRSuQ{{)>B?v;J+Be&6Gf`P-KD-;at*BtjgNL__3dl}kSO zH`n>c5lZ?ZyK~o|)xQqo&w=C^D@y@J>I46;+Xqp{v`1(D@!>zbvOf@9&%N>UxlOtr z2|3DgH)ZVz8ETi5WY{Cm{@nl0BK;OH>mL@-Q%9lFcKco@?)T<=<RyUE*W!Bm-) z4blJMARAA+tOBD+crvuf+iTB)QE9I^QUBQm{&lHwFdCYmTL(6IJN6jl*RvM`SvTpa zN-&xz<>bwxBko)iBFyDkQUbr*Zqff&kSw`_d>*Z{g9&#S{SV7gD+^$R;;*jzZ$9_`XE1`~!A-ea zH}}})ZX_l9U)=X+i~a#}{P_?6;CaYa{(s%np52Fd561FcJ8k}6=YQO!Fu;;=q(mq( zG&S7Z#@D$;)26Y7zUjBM+F4Exgo@SCw0nPHo&6l%{PrKt^l@YzlI zuH+aL3p3Rk?d+SfKIwr&5LVCJyUM<~3IF%t-(1u?D`)(cxBcaB(Ir8-X8sxUN1wLH+k~cLy-01r5ul!ee;FV{GTzb*io2`wXDUP&CSNhTy4w%?R* z!br`5C@|TY$G$nY0d}M3z(36WpT_n72z&U?-ta$|x+Il$y}(VfH?scgk3EAC3dO7L z+{P08^@hK!N9_yPB-T2~NB(Jge_v%ud2nECY5&3hc+OP=7JP#%TY#>LEb3m{eCbZFaKv!Itv$VqSl@ z+dp2Z0;Z9_ug7GQlO;-lEf4!KZ7w}-@$7}A3YogazsbpBp@MDNC$o361u~K%svL7e z{&8x5w-`4XY`HV~-d{t+-|vJg32X?ExlQR=1TX1CZPq~l8$$kM&Ho{U{NtkieJB#%hjf6_T z!5DtCfOeTbB|yCg+X7&$W_RZ)lrv>qiV2xtS(v@bf2AdQ4}eWu#y`t#fQri(S=^p! zE!_F8tS7IY`0QokpPuI-Dds72=6Fy}fyB>MAQQd<0s2%;8Ghr|H)kW$>w`<0Q%|dg z{#sgOdVA;+W}ha=$chBQA3AA7L zeHpBOLp1w2hO3ZN`G*4oef|4-A+a+l9^l7TxyuQ@)`dy zKH?=Xh3l-rhO>cJpe&@z2=sXK-HFkezpcOQGUiLX#ENm=Y@2Dr`-f~9?zB1%-NVHs zGX4xfaS?7#CO;ksoK8YXljpr_7k<7#j0bYnRLYhu8}lsL#&Jh;wRyBeK@6#v!Z>){ zmgo5_KIib+4S$**xa6L9<*Cqc^UOp!b9|uqVnX!Cr`mR{)1?$VjYK9fCz}x0+17^r z)*m1CzOb&I&P;LTUYY^J3B>fB`rOqj*y+GlxX>Fq03JN~pncE4nUM7s5B3O4Nz+NW zy}y{czaost>}>|2=2<5_RPPtA9RDOnLi$GYOWshjyvPXgO4bLIMOn(!+8+AOe9M~A zPNyLPaja-5j?p6L;3#E$sUfUen)& zi1cRsvibduE%bzRp*StSFWfmUPr_kC3lN9w@MH0UbjY)Iy)40TCO->@m^kStvGCzi zy+FI!DKF0c!dHr?yS;20m1Gr&6VkLAhbRW5^bDId3>BuT1a(7hJi2g~y1#-mnp-@01p z=mCc>o>U5Rtu<}}gyPjj_S?6V4qGO4`M+!{c0{}s0#^`8vXOhzquG*+9lttMkrFV; z6(#Gvp26$Yr_lhF*pKGiu2{)eUvXcWFXKazxO$F#>2>bzVXVX*n7-wr^S|rGc=q(yow9qNaW3&u9r7F zlV~986~$A$Jb5=;THTP4*<3-Y?aQ6@=>ev9as18Rj9}LYm&prx1974CXLcNTLg2@H zaTm>h9VnyIy;vhUb+KcnJQKZL*F3X{VKn18#rB~vf7ORib)1Za#|ozEB~~W_?+4qw zMa#xmx(;bpab?zIf=w-EKhJf!OO)lhjao+}{#NAF7iM4o?8NoK>KShymxHcz`CST( zW~panGdqR_A21@}Ix?0t)GYl1j#AAyp{Pk&XYVfp`SN+#y_AoAHv#||e&_c@ie z_d8O^zJH_sCB!uO11ZabRRw$ejjJ!C*f?l9U{MExH7!1@3d)e#UlRrYZCwkLleu#7 zgmj(kp8h;kxztUr(v#={h7;GM7QfutTko}#s{Z4tninzw`&-8s0>x(4+e}jm>*puF zC2n_|-22SF)A5Q|Sm=p%tMUUG!S}2DZhkgNB-HnYT8hV9&2c%L{A|roVo4)wc-*g~ zAv#bz#G-JfnQLBUsF<@^)3VSY3p>}QT96UD^Q+kXn^>}e(VTAqc~choBUuCR`r`$G zsN%9yYt!)(u|{|3RfE_%pM&T1X*@{0^|nRP#k@E1D<)L5(^tJ6rlrx}alC+p4ym&x z)hNJXP349YKLgSmz~-jU_Q#lSWW2jr$^5r3X$6^K-?VY2wp--KcCD?>xzbuql+hVB z1>yV>&d;ojxl2%tH!{MW8}(?fmR9c%Qq#F`Nqpf3ZO;9{OA(8W@ycH1Q4CjHlCfnm z6}Hk_2JT5LU#&8c2F!7x4ZPFWthk1MC@Djc){LW`V_a5ZQ7P}sZHkcaXqz_-rb!RC zIWu4k2j|Fg8Ka%r4&K}U$n{X$Oqfmm1q?Iene2o?tKR2^iZ*+S=gWAMRkj$H(f5lm zn!;w=kxs4&5mKZ3u=g3Vm_h&SPAATli9q*@YFbv(c@ys#Da4$sh59bG=(@W$;Y}ti zbnQEA2a+CTh#nM zsU^MY^x2}VvcuQ9GO*pUSgie<>qQUP}wfbCr@#;(pJ3c^Kv%!gt z!)heE%T2?#{KJvZr1#V7y-UxlTn{WG)W3Iqd-JTc`R5Kr?aBoJ^Wbsl1|q6mA;nwR zuKm_V0v;HGKHVRACmkmq^bK6?LdM6F@*T3${E=aHZN^citOb1FLaMvV8xv?xNV^GEK2gY+PR*l?s!v4(71y1?ZE z1a;G=Yko{(!W5MJ3=rNFRbx4rACc!r2MFWq2(}Vk5%vOYhBERs>h{ql>LSCb=h`5h zrrYOqo?cs?%J5LBLmwX%XxELGY4j7B0$nasvH7EU ziGwGS)jg8$fRu1POt?H2eHSyQMxUrJXGu}aM%o1U8_nqSY&?|_Ja zwqs9_@mn8s&t6$+!u+|n@;rq$C78^0loM)^m$Xk=MGhB?LmP2a(V5d-cUhh&XUFdE zO}xIc)U{SE8Z~n*(`s=ber~6BQ1bmOJEaSWC!bI^1zHp>^xi*v6a5we1xpvvo|zBX zWCcX00B0o@-%Q?RCEY)az^gZg(|xxgi?eCFE%dY!lnxGOwOepbKSL=}yYPw0A(*s8Rg%PMKh#y}Z7B(P z%|`oO#$Rh_R?wsO_+8djS;kGhYEC|x>^m2wb1bdyh4>{TRdnz?NGUp8(6rKLyyIuI z>|g`DISQBpqac-AKTC#r+bu_Mi^3pMTrFXLSt zj^R&8V-hN|EX(&>U!>)$2!t3YSS333vGtxfEC!c{atzHiua{9hoqP=!A2UHJ7oU@& zc&lySk$LG@l17e+slTCAdjYD*ORZ3eV4^lW@<{&pg~yk~9T%D*3Lhure8ssk(a^js zP3?Dpn2=7cr&Pu%!QefL6EB|38*`h>?=jIt^Er*b-a#Q@GLqSHT&)Wyc|~Qdzovgo zgpr#!n#LeAtvAFp&R?+eG&k%tg>1ScnojI>fBtlP{SSwqa;fYbfm~J58R!z37Ji9% z5y_O5PnRLPa;~kRSY#fI&wmSy=tnClaB)-_M}LaQt`P%6^}CS}sPfl#jcimXl93`% z1?5eBPTJsLYE?a34MMp?B~~L(;mzpp9HtD?T~)I+NHv(y0^e=i=ff+%tfOl#b$$?l zaLRo;nm7cvP4=-ppz4lB&8P$vudR$}_#BpqTG3Itj7l_M~m2C0^nT!oIs@E-ZjOB z5A11|m(ep%&g~tvR`^VJFwNi{WO{+RwrY49wE=-iWHje`UiV$b^l||wiAn2XNHMJo zL8Xpq<)2L5W!$@3&9gfMIshS4DLBqFsl_k!MHEZOe;Ba~fW!T+d1Im7GPnRJnca6mC>Q0NFWosKJc%+Vd z#zsMyr^vE)&$I2AO~-@=F9c9>ih|X}A&twg(r-1x;$hunG9}NuOg5?Ma_>lyqw8|` z=5IWj+m|flt|C|=A#zqtiJ#-0$XLPScYeP$^mQhv+SZ=gq5nDri@E)^>x#tu>%A3o zO^MX1WN|0IP>rlaja=71oW@#%tNmykAEsJF#Ad!qD4?OqkwfD3hqjrO??)vr)Tvr| zZlgU9fmE|f6<0TVg2P){{g^~@-XQ+IsBcnk9sfdwrjK_-{Keg4-Fj`-aSdg?IeaM$Xb)sm-{(IL5g4kC^?Td%TqRG4HJWK0y1&bpIAQP&^nG-i)q|FOS zScLC;^+hbUQgNTRO{|t+<2)p(m#{5r=Cgg#RM;(=*k@}9o>?5yT?<(`sAJr?I47wx za=%30c(`b3)HtPZ7N755A$P{gorvf3Pbi`>#WmY1d7Hk94K|_Yx=(%uLBov6**=!~ z+hTM20z^jNbGXhJN@;$mz$qd?B*ZxGc}1Y6eh_AnDC*Mx@?JfU`$DA+6ecszZ{0g! zcfRiK7;OFvYY<=3Q`;LZNrY{y)PZ;{-Xas53c>l+OKtaA>OPmAAT`>_fM(bD7q{fH zA}Y`aGc^pJ$G$qeYdXwztZ+`*>s@J1n-A|5uLfFeo4UAW8ahkZ06opoN)ue2l}>Ec zR?G7f?6=JksE(u5c`-zN<>EtwFxzG>GNBKL9yhwmi0@aA@$P}aJa5)@UlAushWa%2 z(tO&0fBt$0Fi)AKOIXPvku$J1>ZjZ0Au<|@y;YAku8dG0TVYY7@U{!ToeS4^b4Zn} z`W~Fy!+zMIA)gelkE}b>3#WPWCDDi3hb-DkpFzGO<=ABs*eI3cGK76zp>8NxkTB_q7jt z&Gf0Jh9f7bMjbW{>s-t_Zsp#8k76>_6{dil9wEcFv9pL74OqZ8Ktm@3^XQQdXOZMrhu$x?QXOlGm4T zh^aQ8t;#V3)h46WnPyEM(^EokcAetOBX&j96f;+e-)KxwYAuQ)=w)1w95d^2QR?BY zX6;+IL6MaC{p@M|)lISL@eGTh|}#TNJ?hKc;PO|ENhNnZ1S zy9(_mS`wPi?WGn!cvaqyNI!Ieq@4-OgutoDCaAy(v@;0BWfLGtH1W-{Kyz{Uugtdd zn5xmUVJU;LMbb3!2_G*Dv5u#I3lIsGa4Fq+G$yk}C!aesDTxfjSE8Kz32LWe_EOI0w&UQI(SuJ=kFHLn@2q<)uhw5QNk5_n2;+)7& z>a-tG&yNc8ByNZ+h}y7UM`ZO#ki2+h zJ5x>joHP0UmL}%a@q1i3bc8*evMLGf_Fb+^UU=5w%&$1k<}lXIczBuw#h7&ad-nJj z>HUvPbh0at=f@t?2}wc(CR+ zcx!v*FEt784cKz$WX#u%_`|(G>ciA$ME3@>u2{L*@xpa?lq8ulQX7e%(sEy!F@}A_ z?aqbYYYxjc@bVrLhdWnW2X|h7lyMb*%STd$6ReHtBU$aiDfcBmZD%y&^+`-w>0g=a zk_ZEmriVf%5+ z$SU8Ew4z3^qiL$i>T+8$cq$kNeZ8w&umZxgs z0aTr$*rCc;r#OjJHyxS8$*_@{xa%vxs5VHAP+t-rh#4Mw$p--#v02r|MtP|r%G7RMn@Ln;!Csf00g~DxySnM|uiCnCALw%| zkgbYDe-z*0%jA{|?b!-xxzFIj0nYKk#1sSWHr5vyhG^M9MId}NoFL*NL{`J88qvoH z?-b(fgFh2HxC^Or8BQ5oTxd)9V%wk~7z=>U?)~mbbEfN)2H0}Uae+2jrd#h1LbWLW zuEVaK@JdYj6Gy4=0$!o+(I}w7fh*lyOp7qRxYPHR9p=059nCu~?ha*oywT&Q5^v@m zylkT$VG{40$rLz%X`Vcybl;?SWj4{6+PMIdpE9w{Ui&}K%qjc)iMru?7e`Lt?uy_4!Zi7bReSNwYV;O zt{_-Ayw8hD@jSYjZ#~`%Lf6^p+l!H(ox4bDxFX!gm9)_oucZP1)V8`vi)i)Fl8zOx zxzX0YS8L#~xjq_&GCW}0sAT+HKbYO!Cc<_00svX7g%+itq3@3`Df;phIb;Mf*Uq4` zaJ3j?sV(L}B8;`1;^ah^onw6>(4u8cCHv?BfuIVxXdrzN8nYkvs;eUZeK<ttn0QyE*f2H}c>1f4IOajr$;MA<*Oz7rKFJe(K8~^D4Z@)7(OPcmZ{+T< zy3iM&K&mQKD$&;7#DK8&5ep2N+_+3AadifuV=*-KUMX5e|7sqpZFjFvRzPBMo{1x_ zj8>CN`__lU-f@07bNS=BHyn%6^UeS=>k&M-O@w~TO#c|qG60&Vr6h^4B}EdI)fm!7 zf$C3P9x`HFXzyATSh6kP36xlM=&(PG*C~^*3TAelR#N3RfA^c=$F@fTSI%&sRquYz z3=E?h&i>^sDG%;8k9Ya|U#3)~)yXiZt^dV1txbT?Ebl9 zDf>ZwN!W9mOnzez+dKvn3x)+}0-+n3CrO55RjEIwPUZQ~NLvuLr~xLDb=d~G0Kv>o zFpL<;nz@6A>f|iIGMCWbD*_WPQWJWc0ao6}pIMnJUQ@6voKdBH@f?C%!=c9)Pe!td z_CC9=Obq1ocN*e8spM6o2zCDbJ;;xhY zCv~jKXqME)fD_Y?c*3V>z%eUjG-MsIq!nR{^pT7K5OKMiLAb3B$CygZM4&Pn$?r;S(Z|1v zldE$&e)~`zmRBO{(=}fksQ+f$qtf*|uHHM)951Jwu{S_ZBWa*cmYLvW%C0p94XVc7 zU!@oe6AT)S%%GJpFxzg)qf1MB!u=tddzU?6aq*yhRv#+QLZp0=W~v(x0lz(+xG%`^ zgZko_SA7-2-P^tMe+Sliyhn7rWKut^8Ab7q{-gaYP-t?%Lz;H<^xTmTYWhAYD8qXK z%iBAb4{TAhi!Q_S#zhyhiKu;Y(dd_{z$}QBEztvO)O?<&X#QIF%-eigk~ge8v?jkiorTu{!s{Kwp$`Zq5+Gfzf45Gm|FJXK#yXDVkA!)Z-&0ji6IdMtC)96BKq8G}-W;f@B;<(H-xWXyXR#8OWd(7et#w?`1PVosuBpFL z2PcPf81xV|PIGaXai_iAH=xDAe=B27vf% zZrrruo>>t_nnFl#MZ&5NGhP)O*%c*b(9?QXo?WylqE9vdC^k@rCa3=N%5+0Uh8u(~ zWtDBd6(UH_QdyFCCSvEZqyN9IoKh@EZaUK$Vlea*$F#whf zb35C-aqOg@#dH46s!O(7FP-l#H z3Ys(~*tBTd)8z8|GfRj|x0eE-%&ncVQt~Pi_@sBIv_(yao_o*K!KYAoWnH4j7w-*_ zy9{LdndY-;>D)Im4P{W=9I8_Nrs*G!aEgu~*niqrcR9*sg+@*5Ax6s7Kxzi>VoOZm z<2U&D%z)`cT_$=T)-0`zT#Ris|0-}DRd`ov#*Zj@Zw(a zTh*_;FkGe@5f43pw!z^KHDM`KRWF%N4GK!J)TGQTpu(hsQWH>g);}Zwe?IZ4*AMysZgtzm^?DFeeli`16c*WtU^plB zF95|A<+(Fem^~jW3bRv~Q6C5jO8Q!qF#34!V?HNUB2xjt&iWjyZ^|m#PC!p6tMuW> z&!AZ}Z0e+uR(QlV@A&5iAu@r9OA9Cwr0nI?Z5VcARA4gSngaW6`f2g3`Y;X`lKxg91OZ9!fUx~be$Y5q}Bq1$q|7}qfb&!yPv`>TP zf!dvguKS^Z44HZq=Gv>>T3(V&0LcxQlxErzT&Sa;<5i@O_|IBFlU*$jc-sd1;-wBm zd_bE^h)%vQ<^pb_Q5NgzN2r*p+|U9*a66P=_&idZu&@fPOT%u$D)D>b%*O;QjbSFx zj8E=Zge_MKSkqb-uh_M6+`b9`NG$|5dIseuNm-W>DbtTGi501SU%ntpi>QtnI_Nuc z(bKL;VF*zC+=^_-TR%VV1ZRd5ckF4U-C$wJgk|8$^?=f|8-OSb5r8Zh-ar`11W-Q( z8fns#ydq?^;k(Yfg4W(igz+2zbSl@iP;FmN&Y85OaL2ZR zg-GoT0^Hrb1b(lBHj)klxF!FgTS%kv$B#XOku&su^>;R&1@b%x)A@+B1HZ<$4#fU+ zB*yb4*pflm^wh=?lRO<5{!n1;_KnBC$!w+RQ3lAbLCH=zhb;c+ zdvm0${Czy|4=04>-LbbL_~(9TgHK#E2{=)0ENmVkw_2+Hi2HfR`l#SEEogLcxxc=A zAh`w+W6`ot@%P6|*1#-gK0jpMzH;LPisrH|NC1et{(cE|erBNunp}k*W9u zINUKRa*Ffk9X}kP3h_S9UZ;&0l8~+-38pwqWWyN$d{(CR4r$Ta*z0rI`WwIW%tGAO zzw_rUsS=8i&dQnIqo$Gd_J6a3GYB@_rr)fv_W> zs^Kf6zCxW_z?pJi3~5WYI{NPyx>Y+np5ng3DYn=jZT#`s31a}L3`9rK-`Bc-7fIKe z{W~G`Z5yVOv;-_X^G>LJJ^X#f-I>IeP?-HOsWZR(kHh_?Vb({u>2=;eg0)^OTtERFLS9Z7MZ_M$C_QRzeILKf{7?c5X z!}uc73pOX#$@C1lEmZ2p0kKxx?fPcqHbB@TOCj@6*n|Tcm`Q}qc!Q+8TdUPPC+y`4 zGImKTFg{)Otqn^9O7R4@+O1N%vf&F%`@k2Ngv~S$OGb{6*6kSs6_O$aH}P@^Aj&H$ z61eg6DjGPJ`UItD^6b4_>CYWj)ruyA#GkGrjon*AkvdcF7%gLf9?hxQFU#b310i5d zt3`l<3rbXK(){`sXK#8L0W~T0R321;B=k^54HzU&ls6sr#5>q)NONs6`fKi9AQU~A54=pJx+Ho+)6@^O0!{uX?p-Oly&=;bV{X|s z!bsgPJ(J>IIM~L@H3N!H!es}}H4oGqb6~?X4#$H2F1fpi8Mv9G1J}KVqDZfJT@{C| zX#?GyICX13RBPF>Onxrc;q2lSa|RJRvo}J6+LS>Nw3=pV;!oc$0$W`|B9`4&6+}}M zAk_Pe_u0ydNuPSb^P^n3Gd04$D4hTwplZ|RHQM> z)lj1Y^xR~o{;10!dUAh%R>Pn45L!S3#3+@4ZDtu&=^nCvNX($nl`cy_-Iel*>-WiW zL$7`aLav8PHjP`G+c=N)MGF z9ojl`S8-;~aI0_c^l4s3MQM>aMRj}u!B&_Kj1%wqqGD%MhrSA}CQw+RA^H7fN(Z@b z+fF3+ZMB~n)djD-qH?4%@RM%Axf4-&?Fxb&DyNgwofJjqfHSCa(;(!jkuk_0d>yq^ zsXGTvY+*v$I|hXghVDd^uh_!($F1QyFuCbhms~j#$?0h(zghrtL=f`(11hnD$1$A=3OzQUOSIn`cXx{QZh# zA8Nka{6`c9(HGKk2?4fdJMkeDlmZAn&mV#CWU)wiq`2?`@HkZ_^T#fF8gtfE3vwEIpD|jp|XM5R~SP=aY>VYg}B0nB6}1 z;DSmt&K0x0F$#<5DqC+}Ko>1GXBP!&(*?bR^)D1~Qqmt#l3s z=tf*{Kwa|KLs=$v>S~jm@wI%G(sRy5ead@RFGNy0uKqW({IR$0P?Bp0-_d=DWTSosZUMCw0AVrnB zBuS7=B6(}0+XwrF7C{xL`s*9;s*vT&z3d-nK}s%@e@`6Z3lYTcafM3Y1D-}& zIsv#wp~NRN%!vX_pu{8sZSqut=HNPf?B$!tWnTWWqo+o;DFPY?0*Ou-jj92Vv2&@c z93wpnAiy?42y_!|Nd#aZppO!pQ7vp5C2xvx!zanmoJoehYf7&Qnh)omt?e`rI{+1Q zijy{3&es={-$0#w36VuU95&CEo715Md-b-%j3AbsQQaQ>&I;5Mx z`UwKzL)dD`lOr=6&&#Ci7}BY4`Qk32mtliPm1*45_X@$O5;(}zd!mf`S`!{=MH`m4 z%Ift4Qc+Mkklg7rg|myGIG&>yU2YH&sHaWVBFEOY!r#upTVzp6M9Q_O{Z?L_YX%#8jhb=oU{MDu{Y1VL2;5s}dq|f+K9PcLQSD zAn3)e)l=g*w0U?aX>1U=6g3SVK~P)|_Aytgjldotdlo|AqdwzT!Etd0FE#>R&VE+( z1naO8`P>VucfV0(8u*z4dEIii2-*zt5hgO_2kf=5aD}mxj_xg14bc*|AUILOA^Mg| z)=R)XbumgkoY)U#r#NKwJvgx|(m{ziN2|F@ZIoUen|;cRj$HcOC*EQ-7$?5geUI6o zJ2HVuRj3-;t|0~srY(RXl5on#QWW_K$1vt^MU}bE82F+=ozrEbuOK* zNyR<5LgtUOWrrWu>70-u4*TM+1J|Q~o3n&XJv8@Zo%;xmj?MCFVxn#uWR=W>25P*9 zVOZw4R?wLF3yeydsoe{QulEPuvjuW>*#SXgfT@Rt+$r;gS2QYJ>zOoT*|LVzwp64| zVM~aLQY8~)D>+?TtId9hmWKG1E1Fe9#ilaiYLbLov9Icb31`h{=y|I~-_{{(iE7iy zwB`|G>x@Qym%dz&;C)X|iuqOdFL%R#)u53H05X)=TYjRB8#Mf1_tr9CEYGZeUS@^P zXBIR$$$YZ_b&2In&U`B+CYTfiT5?|;!K5>{EA$~t*5_o2ZsP&FMG!G7WXU%w1Dz+~}CB{(Bw?dzBVkNi!nQN$N1lh@N!8Z6D<5 zTPWjkdk8y1H%LM&=CFYl^IVV&*$_VS0Jp37ZI84r)|Z4-AAuA!t*?jiYPgXn{n&Z- zm?l3B!gw>H5no}V3>qBFoaU;UfwZO{RJNFL*PwX_3;AXGk;mAY^8j&VUG{FAk{z&Itqb$7Mhf>)kiI4R?nj}EkHpawM1Q6I2;smEZ%2~QU@qNy4dZn^gGv5E% z5+Yb!%$3V`YH8M#C3^zQjoaH7Go_-S;NsL>kXr~w1cC>EAVd=4+z?SLZ@`-!4>ne zx|7^pZYPrO;}jP3)CY2|utII6t>VVM1akr)R zuJHae^nM(##&E6buxj3#3 z5&FiTsSoK3=VNz&owx*f+2tZW zjy=*hIdr`fnweQtwy^6-+@EUc!6QDrh%=Z15Vhab3 zj6SgQxvep=l($U!2c*v`0Y{7}_* zMTl+=iAPTn%Iu#bRR51toGo-pX-K z7oCigyr^P>oViJtAHq=MlL|2SuaEcc;$Ol`o#()+31HU%f6L?v7oX9tbiBFtM1%082 z{{fM#n#0na@zBH%%!Uam@0V>D^T@9eaZ|!?{No+dyk_%Te9k%U+WM~up86_^pg{u*D{h1ZQ~?6e@$iO$|3^Yz zk`5)+^Bncz?I*xBi^QXx>C0Gds&AbMNz}zp`(%l8zO(kRN-25D`b)1XnmrI=qS=m{ znGe@&3C$<#j#ya=A}Sa(25TI;bf!4G?1?C8%~xgGnPN{Ya4d>sS#oU6lZaSj1y&@b z?Ra`~6woT5G>o*M#7}mjRKi>)KeXP99_a+OLF;?Ypbk|Ko|TuH=AIlIDLYyKIrEnX z%%U=}0+M@)bbAi=+gD#6MfCYZ0pw(M((dcVZ$Dpu=f@s#fq*lsGMj{&v$`{|-pAVC zzJN-`%PWfis!Euz_K9wj#yBfqMPFLfjlyX)pdZjmlszrw71V>jBW1ToJ zM^liDN?B$0gc+aVsfa-PW1X?}^hOSx%)+Jy2WFD}w1%)D<$e*8~80~WMUFy$$E1V0C3EOqhZ9s zCkr0RT9gNaU4jS+0W_F&xoB)`O2rN}iem&2b!haYDhI(y7ETU%Y42AiZ1}0Sg|TRw zvM5$nzl5)uAb?dZv;<-J1?W>=q;*+upAG6%1tfg5fpZUr*-a)Z&BLbx;k<;n`3h@} z9n=-EzZpC`=-h}1lMp@Z;IB5UrsJ5Vr{w{M^5g$PD{=Dk6AIkWqV z%!?m){Koc?hGt>VAL)@1U_=@w@})S!>`K-L2x#?1ZdA6AcUj zQH4_6mEk9%2r~W0N&QZI^@FnG(UbbO2lKx^&PBvxg~&&s+xsl%em6TD%7sH2{KQTJ zHeS(fN9G;-$3@li;iz@VTY#XQC6_FX6-OZY>&ZhwK?K}Koz|09ueZ@%ME7&} z0~|{F96o;kX!vhIl&T==(xdXPkF`RBtY{Fa6yjs1&9Z7vA zaUedTNVMjcZgd8Z6@%i;7>@FCbg5~i9orvOf2HW8y4HSB6*gW;>Ct0baxr~pMD^PU z>yDH7%!dWQH8hY?a9wsYBQs(>e}y5f7?HaU5`(y@5N1!DaEL9{4$jsD-El_S_*x(H zKfMHJxAxqSf0aICa1??AqhD5J-F9N5@X58@1QuFM-sG6E${Al1qZ5PPyM_+R_?7_L zg~*PsUutV9Qf*n?>pp+34Mb^`EpJ=wT(tMR^TFH1UcMpf&eBalu&}gru@hTo6{0mw ztfm_?*H3JI{VCcIDSRa>@R`B4KW|+q4F5%cBkg3bYzD^MpAD}sYmjIQ$YF8lwLItV zr1b=ACW~J1G8P9KkuIDMzg=4I6}94GuVC@>ZNdm*o;(G@baub=rP2I&6d6<`C!??! zf>Ns-PqOcL6A%ZX-ddBG9M*z;gsrBS37j+M)}s??6}U4>p2wQkYR~NrdYTEwphi!1*qqn<{GjGJIHcRD3wV_&JtvzN4DMr>7kJ^x15O zeb?kY3lPGtbBvcfIFm}vKId4qo|0qJeVx=5D#wnTQb#yT9tqalhDro{Lpk_+L{vKV zRhY4Hq0$E~{I?(({ropbCt88ONyR%`5Waao>^DVFkcE#MAhgNd8lMc#ZQGX^_nV&n zu%?{~r0(2KB66PG7!i6nIY$hAoy$ph1oeA9{lQWPx}~LMH|`1rWOqCOM#&Mqxx8?X z;``bIu2LyPV0VQxdDl7Voz|dl?ZyCOh_IGecF1w9SSV0R8=bX3yAf@aY6qnqep*|*IM5?;hyr^cz4AC`%|6{|r4a%( zmoU_s4G597x(w&;KOaqMHgZ%lMhL+nYmGX)papU}f=RoEY2kuEoRvZ$&eDH&e|H_~ zVemWT%s%T|T3rc54;$V7L*uqx3HsZVR$?0m@nBbZL%Ue*=kAF_KA(7%135k(sY|*r zC^XZywb{u*UnB!sL5F}?wt1D#dYQ=VORlmYcNU!BQX91L7?YPgcQEx+E#erj5zs_{ zkbBFDPsKgEhQrtR&OTU+C=~I`clx*{;T9W|CJ-!j;mBQjxnO#E4V;13OC{yA%2XZM zSJU6pS9a}VXwBFyoqk0B22Z6}`i*@Dzwe=;GJaWBzcx{{TvR?c+%=|ATsh<<>Qw9M z{&dJmr$uOP;KkfZE^&8Yeu!!(WBmTe)aRtvkn@35T^Bk`cy+f}EKU#fLWLzyac01D zavVEyH1itv#MR(NJwIK#11Y9P&gbJ@;o#~8MLcV4=1I#=(R`Y){N4Lc*B)!^u^>lR zq<_k~@!?U7IWx^@!+zCt;}w&RSEV7Pu5KZ>ZJ`b1Q>W^#7<%IR-PUWq+{3yvYojGm zw@upGZb5eZ;2hfc<)vaRgPKE{aYLMAjT+6V4tc`ompP3Djizz|^S19J*Wg%m}72!Jb#fa2LLBxID5>;H*lAt}||mS(k&6vcwv!a{ioE=;_z zm+{|18bnpw>;Mb&xbUU3^SKnU+F(b;)VGCAVOj65M6#(RCMKTZ*3A0o%!w&eD&w;E zI6M=xHn+AKL0}4c^=c5KprBB1=kI74a;qfu>YHIZXMaXP#l>pKTb2mf6O+QO63i_X zw>9%{xY_6KQ?4uUWdech&$r~;#7@re^E+HI+H&|x&tVCH5IT&zNoRp$y>T1vR&C^& z`zg8E<-?tY`Oi-oDmJ&jxLLaMLR0SY^wAl0jEZSjk?YsW!7(`aiurihH7pdnAa5#- zDJ$6Cpu(-#epR^r(O_>|{bfx?yndT1U(5B^11?$R@uli`v%XkkPNk!}Ug?FCI`x>0 z_OW+duaCKqm8W}9q3I(u;Vdsz(PceJX@0PpF!+L_lU?uCOmay=ORE0CmGAq(qAUTV zUfEwy5BdG}%f48+gg;#4ivD5mEuNI*{aY2yFZJvp^SViIgWQRVDS;4WL|t+df7O`c zjJa%%S?kFu*qqN`OSf_97Jas0kHd-L2Q#3TaroUMY*Rn5ndwc0M(SJZtt5+#_{e&Y zXLYwqw;wTCdV5jfAo;e}CovSt^JlN_jz4=ji*b`* zJA33rv|ok<91uC;s@*rhkQ;KFg}mTmxTw$oueYy?H;3-ALz(*?mTK*0;7gr~BR3=u zHEI|09|Fx(m~j&xgSCeap13uf|Lh%(FXaZ3*LSz1v8E8F@s?#nyoc&wmUCWYzWd-C zIPw~tU@;9UfJ&ppJTrwOd4}vE9Lc%ak3VJ+^w~#)1{huiwZ6EXXFFuTX)*$**x;)L z)pLz~z^c_)oMTU1nCd%voUm$Yp7+L++|*cJ(VkJ%A$2#GfN3+=guYmSZ54F74x5+t z?~iQJ95q+4ejbzTZ0`JufXbXnX#P?kEB}Akd+%_n|L_kO@lB_cG9oD&W(b*)lcKW2 zK@JK<#<67!MQBjjdyiw5y(Ob$W$&3Ckrh(U{ZU8#zTe;VJkRw!*Y*7M{Nt+kIp_0v zkNbV^`*qJ*KiVjQ2zv+!IdQ`n-sqp8Hk#zh$G5!}KenWOWk}t#5V2bA8p-< z?F$8ecn>p`(kzixE*wP1oFPG}BL%hj8&B}xz8OL8bPz;4`gC0Br`vSSNGBUpBCPs&O$bhAC ztzYIMJ;uRW{iRj;jTwu;DyJ~Rc47QoRLz-;jU`c+ypngrvjU0p17}7QeR4yB7 z;E@!il}zV8k(uwHWH#-iJInNu3}=@dgGowadeLW7AHXiHzuar1jlo+LY;0^)-yCw7 zWW+Lm=!t8ZwH>H4$^^eSTYPpXhd|;pDR)|opv(X*--=GCq|MSqqb$lk(F~JfY?^wJ z7Z;yWub3jZO$J<+`c)O0r1^o8aL8SKZ`Pa~r1?gA zBo3+kpZZhi(79zU~)wTAD1@ak3 zg61w1YXH}#a#6}ViD9wAvpW=r^4^oZildl5XJ;>qNmEXwc4%kEzYy|7(&#D?P$YVaLGByrS<6FCI)7v0XfsTRu z%$>H*7+hbzd~pH?I`xq1>G0ZA|9~MGyP0^7npBU-&RdzQ08QecGgSP{BQPu&DNLBO z2LW9Lb#qeyOVBd$;mm_9z{9mJ6Xza z{J%+O|Len`!N0?nU8AvrqLRZ5)a#I5V*)8ptPJz-RG(jSe*&ozHG{KV6+iL@T6t7d z#@WcYI@53Hzr8uvSHN@ED|aAX^7ed?(Pl1$2>YSJ;li~#qi`Y5#?t(D83|FIys7}} z3{W;(?qa3#Aget*O5Dk@Ony`tcP$wuf5b1JC*quu@~9KMCUGE%TV3U>x)7|* zQxj%eD_x4BTzNAfpC2@U<7-UBIWB`zrJzf8fQ4@*#1#A02rG-Rc7)0j(~vKqJS|Z( zEj^w+mNU=q@b%N{{yNzT)gn2X8PyxNKgLPjOM44IQmsGKM?^i33w7VxwP`=o{VIN- zy!8WZL{k~&y7A}kR}%=-O)bX_O{{jY&8v%YS;R89qLiht0@{kqthkf-pIz3EF1Xp5 zmxO*f(o>!#AZXg1U0twsA!?ut%6|;!Xj4M*-t1F$5G=l7Cw^dNy=6}tZLeL^B}6q^ zU!iQHfBX$a-7yE}Ukx0r0o9nMl)Cyw+k++(p_=q#SqnZMI5*+5CzP(Q_c2kpX!zzrX?cD*bMbq7zxzo zbOc3!vUsj7NuHsifW2oC|09X(EX}i4N87c$+d_M~J=HR`jJh&^q~#^pCZdz}p^Q*e zI*@w4s+u8@aYs*YlOsOW3PSmFVw`FJ_z*JvH4Ft zEXZ}GQNm2UQaWC-HffL0w)I}t^)w@KO5=|WR)Gi`rJhDcZM zr!SG;_>!ko1#+;aDz|`N9pIprS; znomYyJV_%tMn)!&freGM4q<-WLWaZAgsX!5(Gur%D{F8Xg`SoT>ITiGEkO`-GW@(< zrU>|loH5ThQZ7Y2{C)Q0hf`Ym+8-9wO9b{46HXsAI+&gw<8QtRU$v)&Jljy;U4JP9 z+iD+q9?*%B;_=8UJDNB7a~PtOr`47s4B@#zJMZPM-1_&gQ=Y(A>xHck6W9X$g53Po zKYv(=75S+zHE8?CH6A;(`kR-Fkwz?Z0@zps0J<^yUF4Vf>lt_^cp+-4{}5q8tlQka+uZ0OvbHKEfM1I{;WPA14 zh94Ffo0x#TA-|7|j&Em<5(0N4v zNVUEs{pp<}LEi%HiR_;76dhrRQVb6LO*oY!ftl>koCxXY!9k8kN4qW)$ej}XpQ~1_ z2^5l^9R21mL4+K2^;H;u!V(_)hjLUgFoanz64`k*H@tczjK}fuzo_Itw-+Yx@2iGR zhn3VgZqSPn9`~E4Jb|lHbN4kp$Idt!gQ$#w(cwFD961DcE^|GufShSq@m2;HVfQ%lSuy1w7P%HF~r9 zW$wJ{_jV3n0=LtFGy8Y=DJ43F9F{LNY`HU0N+B4q47aTP*M3l{Bjb?{wSO3#k`W9A z(oVYWoR&AN(bN9xl<3Z~f6wUx@K`k*E+aKHb2VE8T%1OcasX&Q~8^gSCekJTCwH70CCM3gM|$bHY@F z*8p3T0A}(1uH_lRY$>hbalAK)_8tH0OUP~uBK(=ZV;}X-cuYOQpT&s#j}eB*U&0H{ zHqyHMwY%Fi8)E@a_3X1`A-o1?#1-gc{o|+xX+1Y+wrw$=?MD9jwTu5@-M{4vlNP+N zO5o=5&OV`;N|B-ScFRWzb4WoJ>HE_9(!XT{{sagFj?evn7VuwL#HI>c7i$%;i{E6UATBXZ!alzOWhiY-<(5 zH;LTo5bI$if&VsPC`Ji6n|jM*JG1*e@4qf5L1>K7z_si-bJQH63P}XgY=>Nt^oA;|lL@@k^&S{7Tccq}t3;iL( zzf|zw6GhPsKkfTlOD9a+Vh>EbaN_acpT|B_hXb^qd=|CCO=u3oum5){t8^m5=uRg6 zSq(2WY}(svhVKYNz*b8wu_;F3v7RxKL$ki9U6hQmZ}|7e0KAqZVx zw?0WYH>U6K6owxnw@C@lCD5Dw!C`SC9+{&L2m|o+MW7I0p-(8nchRP#_G5yADvjuW z(TpB9EZ~1KfEYc5yrdhS5>!d|g}n>4xNnpG2Y=s>ofi#D!NHZXS?>Fbm}>TdYBcE2 zx%1su2VwKNGXNkaUOX0jmDT+u4-=$hI+tK}j^G=p)#JM! zUm}p1dm)g6?gY|JHQT*Gayg#Is#ckY-Yb)tnHB-1iS*ZwL$^9X`-F zN_ZtagkW{<-8srVz%rkQNdM!$L-@buf!2W!9DIZcBm@`6{RJ|!Jtq%eBn*x+qwP75 zEj6$awuCSNrqY@tf9-1wA9C%+8nkz=-Boy$Z}mAoa>9`i9{ClRdcABl@n4e;xC}h& z8eI|j&ZPfqX#C#1f0+k?a1a=J!}%R6@vQvJ6i+_>#_D}s0zNm9z|KF271(TMk zdMC9rX?tYSbz=X+rriGUe;TKh|FK`04k0JR`*a@(VS@-Kgb4kwhY07py=Z7>Sc*9$ z&Al_}YEbml#3n+o|6$`ylvmyJYD4~U|4bh#$@Btwx=6-8)XvkH++c`AnB8U%VTc?L zcOa%|-_|z!@h+(Z=z`<%62<}o0;?6F(P@Jxy}IYh>fAysRZ`NnTe^NjM4jCCf1pk)NdVtlNa{0V=WEm{G6ne*_Nwg+i0rW=Bzu6me9D=B2tBA z4mnlqy>s6v|8oWZbxWVQm5e?q58~1qKRTJ&J^G_k02_Fk=Xl}auOlw`!xx#m>S>PH z?N)yM^txG-<@&RauX-d&nj)q&*Pks}J!#|F61ur^g0(a_?Z}H@Cr6Q5zhJ8Dchv1m z%4F|NLi`LL-gb8mT;L;{EPa@Oa&Vq-OrLcu>hyNXnEold{;gppx&wXH_9kJgd1UaUY3cNsv>9C}%|o6La(N|1DAku8a?9)OCN< zh3>JH}seOm;%xGsG$c`9`JV0XolzWI)^v#P{A&@|3#FGwhx4w^vDK0o) zKjOkOg4g>Jz(f9G!}`Qfkhf^mI?p||QS0(9A|2<;R(|cWG_0(opZ0&Vx9zkP^ULW~ zCM*3Ov0(Ki*e%Q{1Aly7(s-TZZi9g(ToT`%kVd?sJtaw&)2XrX9#Fy84`$C@}PZj z(p24Z_wDBe4MK)GRosahk3x?f4&6}0*Ohdi6U_3+w`0s|TF<1){SjcSrIYp2oN6joUKA%QkN)uM#hU?c2a7+}AzCM17;%6#OI&Pjmj_d<&d#b+YK{b`*DB+L*6u>nuasWRL34jayID zL$J!!9f7L+_@67~O@{=+mB^vjes0ze^+e_g!_@0BzN` z!-ii2jt-2n(EQRTvfgQ<-H3Ta!a8gkkAHS>;z0j$3p1%6J7@txZA~$Mw1EF}Pixi5 zVbwS*bAfAaoMKB?6c4845@BO8nh~4Kl#IlNB?ei2x2_m|8oVND|DlBD%3o4X32_YT zEejteoRfDb41~xFzeSWiJe$9!=VKyu8rBEclaxxtl4Qh@bj6CSn#Zvzpmc%T19_vL=}YyxEV%SV|?kFmXf8j z>glLhsWY#V{lG$owR^xX?m3$6x>_6D2G0nl(A|VgtXTJ*R>ndF@~R4S7(h zI@%`(3Csok4s<{oLEZVGsfhRD*WC&hgs9PVT5@aK7`EoU`j=vkkeGI;QP|FdFW3`N8!tb# z_Bb(YdL#3P@Xwp->W2g7Kl=Ton(8mIe&OlFV47cT5W20CRUug-grL z2Q8{@#7jSw`JOJtDoTRCouvksF!Cbrp9m%|m`}Yz-I%`QD*Mlt^4Tn3e)XkJVlO;Jsia6~@zQ|YlS>v-*7`ehrGUpl+ zqc`nmMXvmkcS_<20pv_J?GV5eyxk$3FJE?fqWU^vbXzk(`;(@;2o+;^Sm2Q>I{lb5 zqEapCmY;{1f+q{3Y&Po=6X`FnQbjJ70f1st>N}dJMF!OHdvrfS%PwSRT?rhw@)3v$ za}A{H#2kZfsr#qK$MJ;Kx-0LQvJJuWE->q)UM|{CvUu>8Y};}XODRqC%JJpr1}L1! z2!xg-l{lyPHHv=}-Pdg`;^^ZDY6|AuUXZFHoYl(bBK{pp6NLp1CdrwfN^RIgjJU|k zU#lY9BV6Gre>I-zf`TNI70JB6yUwG%13sCrNW>byMksNSbl`ue33jg32p3o+7NqLM_t`o&BM-IQftR! zt%Ud|s``cDHvW2*cOndED4c(Qn3^P?F&Im?kY-~hr4|e^~tH3hgH!OdQ$uG zWVF1mB7D)Fq|3q`&A2LNi3e1J_?D_M!D}R;c--~tFQr~6G6{UX;x7?RH?-{%ArFIx z$25{}?O0VL$VIDsd8rHD4o)u8GD)w^T@N9rg06`Y0sh8L%vagncVz1ew$6y^H45lP^~aiV|fDaGg|B>_25Q_@K5ny{t1p)@Ue1r zN}VQ)Sc|YxBoPV>@S7+jw~(^dp{GHfjJSiZM`_o35me;>#1-yyv1nT+qd$_&<9NHn zvhONz6HI6FQ^;+m<2YTZW*7M4S(i&capoQ>mIYaX#V}WC#0UOR0Uj}x^kn~z80~=R z1`b5kb97*X`yu!Q4ETrAbD>XTWwdnSzX>})4Sr=LUZiP2Y*#5wW3mz!<%Lcq_0UNz zQXTswx_xm+kerdfeOPFK_A(!Ljejmg&zVnMbP%594<3XXJ=k?Q5=XO^=&-OOZU}|l zBvJ5xs8sl>IUaQ(<@!i_7vJcu<0SKQhi({N7#41S>9*6YBGUufq?31;{S5iSh`oW`V1HJV zZ-L*(c&F;9s8)8W| z{Og+$)+%X?xD5oSQ#hso17{uk9Z>OuXh8zd_5n3%R&V-tZm|Vb0}0CU6ST zagRGubX8bl?Q9$5cBjM<1>VPdH)k9?TPr-W*G2g7!`j&?rUnuhIF$-SjQU!Z9w#1@ zU5u}Jl}KsP8R1cM(c!6vucajg!W-Q0A|8QSF+LQ5-Nu|Cah?ijYIw9nbHlNp6y8A| zNhEPxQs|D2upUWMzTw4gFQ3T=-dx;XR1UGrLeBAe;klXn#3=X5?9iPJIKuw^-JDjzq4489X?rrFkWTSW$DsE zw*$&5(d{0cSxodF50loPrc9{E9*NiC$9J^12bjFm0*y`PRAt4Yt9!y%H6L1<;A>Rm z%J0IaeS(RwthFZP^hh{@k_8r`8^*PXTDV^RRivh=~bD& zo20ReZ_FtT+%HsXGu@4CidkWupM9`+(qF!E&lxh^z7FH&L*VyoMxXoAJp1WxlZl3O zO{b4;DEkHypsq%Q*Y}BtgFBpn4CqiMIlle=n-4xz2pPWEL%LWLav)JguuO~G{VKU| zvkEFi`6ZM*RWi}k zuAJxH_6Bl;*7%v!gKlv2ZBsYbrGK8F6^Qd6>A3@e(~;SWQ`O$s>l(ctO7~sF*XqDP zv<#|Is_vzxd#=Jm{uEtk3>ff@f>t`jqbLCVBK|H*BJkwmXwo!KpYr3AlDTYDVT^ zU&+CI_QiFR@G{zf2TBZ4sK{${%YmZSM@NUj3AZxjcZZH6csnfnf0d}gw`XDE{46}D ziU~a|u`lQH@q_3}Nac9EqGU|mshTQPq{B?oRB_za%*DlpIe7TD@h1b~JMB|~)=qfE zI}UWJ0>8RW06X3l-%irh zY?yzLJMT=_(#c_0v$4Fm<08+t-N$UnFh{EyD;(i|Ga&(l6N0h(5QW>@8$R`xJM|VF z^N^%zR_(%3Zf1^PNhTH&)qghb#O*P!x&2YyA_Ul-cVotD*mXV2Z5@~NI!u|;(DTBM z8-y5%Mz#3FVv#8~AUfQ3?0^qQZZEiSj{%cauPlpHb8#sfYCCBwHj;5w-jL~^x6PAi zxl5nVU$p03l_esANizAv{76K&Y<7Hs&aOh^SHJwQWz_?{!Pnd0CA zPfYX}%C%Pf`!)LyKYK@>^piAg%2;L@*NLWp>oVww-uo+UWFZIi1ht*$gPWTn z!tYd@9xavjj5*M6r-xAPCBE?aNzFO_tE6IkmEPBFC##@gHsVw<@4c_8lbcK3K5_Ew zzAEg&kjq}kWG~CXAyl&jjO@6A#}P4_Ia}HjKlDz`?J@09cTAdEsEGAM2qbcbBem6U zrZwImm2KrUCmsKJSYw9SqJWz z!}U?RERrV2(JiVhy`$<1#5&=DD#0e(^h%9{aw!Fxc9cIogmt)#f;K$yW&v=}!=Rq6 z*A$X0Cm@wPZMr>G<@#Zr*SCF;oUMi`&%HPclXw2i2GGEd7w{}fj6gVE@8TYR4=}Wm z^b)S6({Rj;YmoA*UH{>*O9nJ2Y}5iUm{n16r`2;vp-m5TJduA)%jH`xc=($XdUgd$ z{RJJLQM7K{eztvxGOXyB9Gf65kfR)sA_&6CvXE*dL%6}pzIIAg>a@o3D3SPNgmBw| zaHU+l=#L|63PKM`lE_KH1@OIj3t(AZ_CTp^BNQu#7j{Egt}(Q!(S-`En>kPk83y@+ z8^s?XrLb{3w>JVHBwB5zTWf4)I~%={!US4Bkq;Mi z$V#=|uCEwdUW0=FcRFt!O2^Cmn|FOGGiW^0mVP6r)Nu97&=6A5YgD&2qh9fP$qGPE z`+hjmn-7KuPP;*ZT+fV&<|R(`%v^n>y`lU|7I{?h81zoL)tRYnazw~Xt7X0E+Hu!! zu?_$&-B9gAg?pzYzokl65yXY1wZ$p?6@`kShC3(|`%d5}tUle72?=|*nzsDPW`qCy zJAp1xLCXHa(%1J6G5PWqBxh20bFd}&DnkD}HwtTq)Qx3m&eDDBd2nZmoq4?fi>j+S z;T)dY(8yr|NTa^n+|vT^bIw@)&<=Epn}^&IH5K);?2g)urM!8ZL+ z63_^TZ3wDC10+crTrx1W!d#sPM4<-JRrg)H!vGeAU}NRo2zqFYbxV-=u}&43Z+yAfUuHNhty6^!12B6=n4}u zH=AgR44(>Nr(zVvm-BYct%*jr%Ym5ouy^uiJv~*8io_Tu1D4i6Dc){(~S~VEG|(xLY4Be{QXXkGy^4R2;%##je^8 zY1Zj=evIckpV0AEx!z=Ez=ftPJOjA8iH2+Vuj5*mFCN1k?9S9KiP$QH1o#F3=^IYX zDxN?}DxjB7+LJnyw9A;AUt7-^cs6L}83!&}kUaqCx?MR?G9HF75`fg}`p0vbRb9o~ z1hSNk`c_iox&ehHlH4g(G|W_$SsoJ~K^d~yTin?ad#Mq!ipA7rv8DE}%Az(heWCJ6 zJ_qxPy4Olw|HC=2d|Y1`pdhuG38mur21e4Ila4e8u&W$;GZSn0G4k`Hwoos=C#%|gT;XRV!CqL&I!uL8UYta zuL9}W6$<^i#HTlV1(h&<)M3hG3GMd)NvT`rW@s-UY2e-pq-FrY7ywM?SwK~Miu8$V z^N@%Ch9KSJ_;ggT!lD=1$QqaJRunJh$YmHdM@g%p;zi^;VnpwK4(aL^K{IpOokj5b zWbq*@fR5P9p^2hSWhYOv?w5~Ed;gL(9O`QlJ(B>S1Z|Bp?}&_d3-yrW10>FZ&;1j7 z?~XIH13NQBdS>O?`p=4qaFPp|cAs?$;V_y0q7&YyXq|<+nJPakht=mO4bE`v0fY`y z&LDRGqV06%J3>%SVvu-mtHb)OY#UjHzBS074wK~C zC<((e$wyxpU<*jhRx*|y_@OYu;hEm9oW_|Ll{TY*Z?%OCbrw%=KAiUCe$S$;c%c|S zfH0~KF8}$%3G4HI`ayYYwqH}Ts{04VL1<_4WV$mWysQ)IUG*+W;UiW63jLI=Hcj$8 z?B!)o7P7M3GQFgvEE9%u$hPiAVem5v^=f#Vj;xy!*by0KJOIM5Ds_ zo^C4Nk@{%?5CT~CUoSL+=4q?Nkgs3r0Iem&aBrr{AN5n`wyK3Pn3r0{`JqJEKPR|y z*d)%e3izSMj3Rn#mCTydBA}2cPTUN-mA=*=y7hqKg;!h#&B};tQW9lsW|mvvcj$j( zjm5}yNdVH>oU_qjzkJ_4JjsouncG;iqD1W>z=}#|q{=u)a&e2v8-2rQA~=mn$=hwo zJ)#R|wYO;ZB*?dOWZ%dlKRMX`XvE&UdAxCtp(+g(`Hab`FR?{D8sYNoHZAnqhcP!% zr1r(W?GNjrT!7qTPDY=Fphuo#iPIQSZ#g(E05(FH#MZQ;kFh!c0mM5%^AD=Y46UM8wQ8#>^oAD)ck1ZNeAFSs7=!Zg5{ah)%Bb&pm zJx}JT>cXy~f}Vy>R#%-rFcK9(75C>=I|UW=XDC*0JpYYdB`JjYlGmwcDpPVMwMO$T znEbi5exY?JqBG57O|HUpWolDlG*<29Q^r9_DE*~7 zI=fHXt*03sEy8OVxd`iM%G%o6-stiP-uwv|sCgH~lc&QJ#TG9sD>Z+x6|OBo`@h8= zky0YLGbkkj-fS7J%H5rbwBwGTp0N|V`lKnheylhku{U0#PWK4&mq|~f{3%XkXaAFA zK@CP8=XqufwXcqjL5(j>lFR1ms${R3`DnF|(P8ZzgQx3IW77b=((mrN&^t2^>WR!z zgt-1;uO3%@+nVpw`_&x8Zh`v=&$|lH!Wnx<7CU70_>#6YRGs>8G1y+j2?(3@3p?TL zvaj5)0KsW0#ga7#h++bOR}?L-<<3J^5izkp45?X@NR=0icHKz5j>!ZJFLrk7_Dt>b z(BiJSTcy8Gq23T+k>2%66#+wE{BW@jshXVrR_?ONBB=-ZT`&cDy76A!l|b@bmw3D# zmv(V`Lzut^q&=}w8X8mDy85^{$ityG$+FUo_{M|lWln4P*vpO?AweelsVT!ntdkSHgW!|(yqqEN#0I#duBw)HX<@Q6CS z`r)+9Q+uQEFGOf6N}pioQJkslpAvkv=iOA2OxUP}oK`=-0Lc4$pYP7){-f%1=B9NO zHWh1t|AP95LpV7*Qsrrbi#Wz!1)T*dln;*yqw#=npH{J-y63Bl5B{O|{Bk$(Ah|J{ zhlTkz$EGABp3H;d`I$)$3dHyJ7;N9{2GxblYZ@%ytf`Zay*@T}uI~vA@)-n1GAtUX z%C?;zNOT8}cqnF6D5v+Q)OP?#>KCUcC`|-8^WNSI$p{QYl6scTY8F1m7Vzy(;T^|I z-XMiJNI_E$6u7eP$5cdcXhF3o??AEb2fNUOFC_(9rSQ9_9_JMRHui@ei(=I0S;wZr zOn^nofwnxSo5Z0T_aWv)C_F=S#GZOh6vLgpZbjx1nu`q%CspcF>O(zb@#%qC?C%oF zkt(M3{qmdTIkpo3-)6KNp>kIxP>_|bBU$mdHDEAJmIY9)wz`W>0=#RkD}s-p#{j;! z>rz6E?j@ULNE7n&wTycBw6qWQ&00AlsxMo4QO0wC>EQD=(pa&lNu5$gzXJiR!S*5GPw!0u z5YH%CxQ}!KOMfJ-%8W}hH@l-emn#7;gY;CIK)Q)Va34snZwFYM+h1Iu7TjPTCbbw7 zE{HQ7Kda4ZySLWa#i~5(m66j2y#o0NA@it=!6ZSwYI1&y;mQc@7TOmIWI4_*9bw8X zve?u3ux_O83{YbPu#;Kg&5S7;E$|j= z@|3q!vPtOD$od7{(1ixfQOA16CvVU2OCx&se=@>TkiZcBW8G*iURprEcHen5jCSj) z3xa)0Vanc;11MPb_d<}8X8P2k0v6>;={{PHqo2-UG>SoH%R$WZwa(4HpX@|Qf|jF~ z<53u$zUAq*#yzYNw+^T)$#evRn$5Tgt%=oHJ!`0swHDHJwuWFt@L*}^nBQr(^lNk( zh3-iP`$eaius(9JTs(6KUV-&wQ{JNs3zfSBLlR_^-#$7}5Lg(IWI4SVmZcZ2vW4$n z2-;kq0h={fzqy0Da;7)Wr1sLea%l5je-t`i2}Vp9av1=K8rj~@w2x$KT|vuRiM;s+t=VUqUqe zMk3EUB7X48NG*t}VUXpHQ|&a8bE&7q9eiq-)Q>vgdR{W9o`=sQxOE`t4C{FE6<7~T zX5QV8CpN{`f}HU!Hg73}Zc~i+12meTYJ5_RdWGwj*or)s27jdU`}z`p)aIMr$3vhc zQnjn%#Z*wo-nQBDGbYS!QEylY-N5&T>2GFBJkBpqIkfDrzfQw~aXlx&89QW`;ir+P0?Tta@d#M>8e2j= zlF=f6M7F6WD zRmO07X89W7NfL2W?bMZ)kMx)G!2R(C>1{g!ZOvr*rRxx5(jYA(U#29l$u6Ht6_Y&~ zeSa_=P`O1)3N1z?`N5IEZ`gFyDFQE=+WNu?D~7|^L(BWVFPyg%nG|E^z{nFoU`FPq zQ6`Z9G;IL;pW9K6!YTO6O#0FD*MjqhYg+k8I7fuY$T^p`544^|8)N&QxWGe_bl-ZB z+1|8v0z98y>oToLuxjOCp`9YpN0NwIWAm+)#{XL zmlax@A%-B`Q*<)n;PY#D=*X$rD|cH-kywe6@X}gDNsyawl>#1H&9^s7qp?dlMb$A{ znQX+J`q!N!o^1QI{sFD?4to5>j^C3SaeY~;J>X>_i;S3ilDjep*0}FXH>?l`@buJ9 zPqkPQh)S1AI0L?9#I`-T|LHmVU@pJThar1S_`2t7zZeQ(`HJZJ&Wz?GBv-L8=_RFC7 z!3zLN@j(vC%iH#Efjm!-#bW^<;TF<2E~-j4_3-D`#K#oa)JD*EOre7U+4B^R5c~s& z0awfAsgHs!$w^$y;Hp?lU(*IJ#`Q%0#`{SYq4?dp6;CqNiA&%6Edm{x4dQqLpleHd zkVf=F^FtLC4uG8bd1yDqk=wxCN}mj<1g0X+*?z#{^7(QcWY+|g=JJC;f0o5uv`Zfk z#uN^Fb8`09({%uX$hMAKG#UiyXHfqAtL)}Yj6|C)4V}$Kvahaw-Lt&4nUC?0GKyCK ztE0z1yeSl9(2eX{7f<+4+Q^KY4b3wj8q`8+kvHe_;x|7?26lquI%pOJk%xE0yt9T%`3UW9m5lI-+slUp9Oy zwTL%aiPeARelW;qH2smCTzcI?6QekfD$`JoO>Eb=7%3%NATSH%YgUXqk_;)(;Zroti8 z{?z!Ol~Qc7>()kSPmZC}e3$FyoMD;>4%(>GH-DrxZ+cXSqGC^1y{m$j!$kQSfqtJV zGV+k>P_WYJY(#0O_)xbe>`uuej-(<^*Hnq7doOi16Ndxzoq=vcfhl#hrJ^L*&n1hf z`ZuNy2F~8@IS#;9tCYB(!nQN2ifi@v{F}N~qwx)bcJo?8U9FvwFIg1@;YKXEaI=!C zfFL8Zo4#6`SjVkG&qBaCbwk_SA=7t9AG+l5(Q66w-+O8Jv&_+1R6*w~J_BB(;? zy9k>^M68JH62FM~?XJ$wui-sWYRVfIVW$*P6wseoHvf=ntUR`N3pAo@5kJ6aWFdRS zr>#!RjhVHQlmO67-yZ08@?yVsxpUD#uM%;%vwX)(YOQ*VgYl<#&nLhv%??&hWEHPP z;pRDX)-z+Bj7$NTD0giDkX0H0*u<3ca?vgmJb9w8rm;@fTA}4w11PlS&C>%V1p^m8 zDk3^Nt#y7ygWXfmDf<9}ch~xUS!ap76JgN{K_2%I70L@W@m}Hn&$q{a+)8sytq;YY zV|zH2H?8G4@S1F^ROiu{$LZnk{mUEQ_NaZCrXV2?Kc2vl)DxEl3;`_$7raJ4>Q4o!5+aWp9zu{nNAn(M1wixk?wy01Gyw>=Im{t? zVL230`RB!;&!4!qOy3N}F|lqhvq9HQTn<1|7>Fqn^WglxLDZ^eZkd`^C6C+F5pk@1 z?gQdm8f;_KY;&R6$C>K_ev=6V^}erD5zB^G1b=n-^*gM%=iMpSPbwCGC(q6_CG*-# zmTmvFE)S2qAm}ziZ@nn^0V5|VSmjV%VS#Z&uFIYL$0Fv%1{>uQ()&@%bI|S=3BJ7g z`Q;wc5(tN2+2^)l#N{#l00}-63htaHuiVm1`9`1o)^q@nf>6urS*`o3H_{;LAb2i$ zB~wPbx9a(Jk_)8^ahX}WbvcLmM?|5{hA2GhgB)2!bjQ9AQ$vOur@6L{c2*1+O_OX$ zCHxLSReL0d&GOP#?%U2(t1N(6+0gBXos5`jgqkNDSW7Wsbr0~kRLM?&z77^RH@>C- z)~X=*8&;gc)&U+(9+v77t^RHga3cW*(`@&Q-cJImfpZt&PDN6@aDjkH{%9AX%tJ7# zOtLsocoHoA?4Mr>%(qQM5eEuU5uxu>@qP^wKNb&ILzpBC>}|*S5)Yf+I5WVm%)=fw z{w^DI=9Rgq9Rzk%en#HvK;jUbFWA$^?fRq6H@FkzDG1qzNY%$x77o&ZbTtj>3b{52 zXl#B^z*l_-q4rwarQWd!_O>B0SjV`cH^)$MQ&t+#f}oG2pzrM917B-ipxMTko+he9-;f9!f#) z{s2BEQVy2khY~Br9$mDx3(lIa5)ZF4U^vfMLx?DR_c42>ku=}tb^MvMBkiE8Gyoqk zQA^j*g*jsj z1wg{hooBO0e7sB0gt5k}$trIrqU2Bg>B!kzZX%=JC!HA@q9uj^ZmZ|Xaf!jHpZo$n z2>7DI=5^m)_`GAXAMG-?)5k$HS7AR!s7rey>K3x-04*Q~1LZ30>6^yeIRpz_F*tre zSiB=~EAp(a$Co7$NQsMMtu)D6nt3&dr4*AIczA15_2ilOxo;pd15)M_ z&}|6xKa~@BohG0a)3u0~jthV)Xk2XfW!|9*f%%}$-2mI50f|QD8nwwmG|=?!hg8wP zIX%GA$?HhThi=^om#D2oK`MQX%6gd(Aa4AQ%XdpC!1XPo4d$WE38MU^rt{(V=6ZWf z(uR6GbT2*HFYw?W3O))3!3N`4+(B?&86gpo9^aJEu>8BKXBB40z{uqX(707oY=e7; zhF{Hcu=Tci9S7BaoEz2+HXqkUS$cnaXv4%;D6mES?$7M6pog zTZ!$TG|3?w&vbY@8*dmgigvk3j!1+rIM>I=tCBS7%T}0PPsQIuZag?2ukMSro$Z_e zPf&ws0^ldVM;cj*JW8KY0e9j@;y%=Z^v8#)hi=xKv;GXPILr7+P(x&=*6k@V(UEeyYz08X2Od9xjkJ$F|LpExls z3g{5Lzmwwri{XR>`y5u`t~+4b>>ydg_m}_8yM9LRs4guNntq}u{tLOPV&!^)`LAO3 zRGlj%R)&xs7V1rI6W=<*g}YP;Se*e|I5aLI)rAW_$CWiGOih1tvjnp8NVqD19e zj8r{&BgAM8AhxG48IG`Tjeu?&N_|X)EFA)kEX6Ui=HTVEuVZwZ zZHav_fcn@oXbGNIY4;pCOwFhJ_3X(Z2n?E4YCbZ5HoW5sa2+=Sej9u=JPV8ZNLVyTCWU8Vi*GWYLlKjXEKhm8X)l#FkU z4n@*h(|JgH-Y|$6av2FD0cz;8?$qj4c@^bXV|Pw6#?~FRenJmcP3_r$ z{L7y~SpmSqXJuJcdPsCQLo-ii`EBT77hO<-5MP`_a3ujauG;cQaFv-c9-rhN3K{<0 z`hEhh$z|f}^^^=eT(=pBFk)!z{UcxyL&HID^jCD5gPfGNbo_h&?GK3@XUNTb&}g!h z?jyeva{N_dTHP6vP8O2{YRTppH1Z+%scmOV0JyLA3H{4eTf3H7hzbY*kmF;c?rhyw z%lIpPNPGIHTbd>J=APv9sH)J(VX`8UWHbQ*G$A7>4|c7$C8&-1*0xGKTk5dHXI2)1 zBP$#VZsXlnIU+2*kW`K)sU?US(s_19+-tvnrDx`bf(jWgE+-|)R}X}5p#wO}<^;V! zm%-MWq~SZkr|>)_GckjG_x_`I{pO$rymB5t{dYk6mg&=c)yos>q+9$9T^*| zb0%r>E3;kAfFxIm*rD{SDwu5O6G2mgiGxb68|rsB4dsgcO1@&sO~e40PH<}c99c1S zld{TCB#tsKBd&J(VF|c1CE~em_vPbET)!_~$+4MMj=vS*VR{@a?NLWa-^hlHnU`B7 z`8r7Q$IIe`#Tiljp$XHhkgVqM9~U6EYp*pD_1?+$+=2d}RDo;58)@%_1ePA6nNk3} zsO6&+c2IfvVG&weq>A z&8w(i{$d<>5qo%yWZ!b-cb}MCpgp5;3nH*frF}F8#oqa<>YkZMevjI>ue~htVFBcU zkTHiUxBCo132=qsYt9E2X%pG5`W35j3c^`V&H$cl|e}jPOV;R_je40kkVWOXC zf7_VN!rjtlF32k1;Fv=qav=yhACfMmT#Dz5W z%|8*;mP>XE!hA?R(>5sG<~Vp6I<=tL+%@lB)O9S`28AjOAJxpGjWN5vY7m1LKAL+r zQ%f$jWfqR2tfALQpGt1x2;A=o;Q{)J@&#Zbp}@}uBcLNA{o6Z;HVeD>6v^Nk2zw1O z(V-+3e;YVq9&;w}#U#f2P_WB__ZTnJ*mD3}osx3g+v<|iAt2q;x}Q!Em>qhV?AtA| z-|7QEPfZyHEQQZPdZ;erKU;w0b_gYWoDvMxBTd#FG>~dFp|C%5&4Gt!89^3P8 ztmL%no-yKRI4VXm0F*NfJa#?YM%b&KX{CY#ifgvL(2hVK{KLWD5WlKvfrqNf_-nxL z{s1XkwPsE!GFrgy_+9RUUcBl!n>%LE7i)F)2t z=V8|Z7RC_xv}KPuJNXJ&^p53z91l_@gL)Acx>?aUt>PqprUOFcx=C`OFIKb+Ij=DK zZxmm<{}Vbb1ljOlTCCKCm)f5PJeX(*)z8JnQRTN4s9d_^snyjiBG$Euz{?;up$zDK z_=kLJ+ZPu3a{@^$SUM$IL7#%(Z~C6f-Lr`j`Qjls=7;&zu``N$t`||093$HXHYhF@ z-DEz6-1vo)!_F~^2y-3a16WT_ts zYgvkPiPY7q*_MGPSnHoQ43jG7dru!+j%j2i|Bqt8?R_atE{C=@{jj-^z0fFN=2PDQ@VG%n=)#019H=7sJzUm=k*>IUTZM)zfmATGc=kU_ujHYePb)L8RB0&)CY(-m2HiPrL2} zzL>bM%^7sStab<-75**!&;XnQ*;9vM*Fq%N=n&J}|5D{TeJq~Qw69hf5_I=u(=f~; zkxw?InM!#&iYaR&QkkM4$ho{>-Fl7nv}k_wh0SitmsGvIfMWhaG{gTR?8eQ_JX7p` zSGW-QCxV@v(2Q9e>L{ni$n!$eVHF!4Sq+fa^gLyFTq+d=zYmTiPkRh*+3ff^rzce^ zlM&VmdL>tQSn*%L&Mrf8+g=~bGfC~&4j$;UA$Inc8h~(>Qj{>w z`mgZP)2=q*rg)^@a=tNCOvn2z1S_w_1h_Noy{oH0$OX7N#-)VM3(y?7))58`%A~Or zoY+~=KlQMeJwvG{>f5(Dr{ff}Q<>-9!xIr_aaqDH8vx*ZjjEYycE36Msl@Dn=%jkg z3<6RezLpDZO>05V{&^NjBx=&P700wIFKryT1Gb`cpCWz*n1We!N|Lc=@5b5a$dXHr z@(E`(j0JK_cb)l41R!WgEC-Gm{T@zvM+rc*-H%9?_l2y71#v~4+jVB!E|p(@Dw|0X zQT@X{Zd5_nF`AfUu3VsVSDzUTFz9oOpqr2!5=GLPhvq19y-^F0?IH-Wuh9WQ4?hP} zsscDnAgtqr^icUf$odj+s<$ufoQ^t%o)RG;GDT#bhs-jS zc_@jLP(&n&Q%E90lIUAo_ul^B_dSp2KIN8v=ePG>d#!i9@4ITu`5iaqj5Y?1qX25j zJ-sF**Vm>z1-xPHaH>PUGP9+P-%9nI-pT-+e*>}@Z7@OBE;p`l{yo$HkinJa`X@zE zw&ZyyVAjm#40VwOV9ZMW14wF)^`D-A`33dwqD~L@qizE83}T$VfeCbd2>eA{xBEb7 zV+woo%lXh;p|#a5_SR{ms1G~q%g+UwkpAHKf0AL`PNX2?Y^DFEjPzIFC*!9hJaZ~n z?OXxn4M%aL!AsVbH>w;eaql{anCelWnKQ~feBn1iuWTv#KKI)F?UFmO-;};!V=h&f zX&r(|%h~;2hYMUNfd2Jy^Y}X1;j63h6*s&A6g=oc&y-kHQ@U{|hd)>XINaN0<{Yi` z^#|@eMC-MRz^-et2iX6;t9P=QxtqYKzE|6bEMW9%gYMI(2^(5lTd%G)qU_u{s9Isi z!U+KTS#RZ<;o!32-}>)UW?$(?KUw!HBzF@st!}?@)3EKCu0J$Wf$HO=)!_P03rel6 z%$^!NYzg{D>UL`A0iMDGgau&ccCa^uJ^@P#NbG~4;;8%Ch+=IVC{7pz0CO3~w5r&i zfWIS((J?KpuTTDb)j7koSD!de7px!F5TyJc6MW~zYoHV~G2P;?uCyA0O>e?{YmIJU z3Qi>O27ti9j5sj8mOC~)+Aq4K89}9@7o;JI&osOd3Zhb+8`r6ofHQevjMv`+_wx~F z_{9h?G7>ktgcvOmktlX)i9i02(Gmr+k|aw#$$%r)U&vSdw&4u#uG;Gb`pHfuwumXA zK-VYdmqoR(0pv@~13XOO9D1ZAZIvZ}QkS)MJzTj7#X^`e(}4NCWP)rB`yqy@iZ~sX zcZljvKpNGKgy%2+4H?1uq^ZFe>ymwN_GbrnWVwl_-ej0c(|G|?%dSr2^5!qsQPeA!jABG9r6aCp+}i1 zjo+h|j4du?dmsVFBP84zZ_2v>{{;G>LGrnQc9#)+&PqSx@_w^tx3 zj%kzr!;ZT!y7Jqhb`x^bVM($Ea3_!>wj>iaLywsk&(8aFgR8Ao#)A$$;m&9GhtFPP zjoF2M8%(d~t9cEn0zk5jd8;c6+c1gNy<-m~Oi3+#K9Deh_N_|5(b170nr*XJ!MEI0 zq2C8SXAMILC#XEl%*~yAAM79O-O)I(J%E3Vcx?UVe@2E&5OJO}GVc9Pp@lP4Z?}xm z4ep0<*`je`s{YT~X*|1sLzT(I`TaJzH8R0_4bU$P{ z1ox`)wMszqZ>5t~Hx+EB)25%NWY7y3kIErB`IbLWgR~GW4ra12CC}A>^-TETUPPZk z4f}(V&KJ>r*8KyKbHSQE4b80(cbgbz0m^0(+~au%%^fe0xrO=t{Dcq%YIS(s@tMYZ z{=(T-uuRQ-hbfZ-vpfJ*kZ04t{H(qYpeSMb(PGd1#lc7mK zN;obA;;y>mr{1OUhBct+R%wtGoR|$*{XG2qCX0-ip;yst8=5lXmU9he#HPVO z@3pQ0G2ecf*i{5q9sPW388d3deGh~_MjX%%)Vmh@V#+w=OYX}qj?;r^_NPpLa=BbN ze&Sn;pY+KL`NR(MGFgCpzuZlzn7xHu))6FNNRh9ZB0K}U`|m@uKY#k^c9X8L0o6V0 zz)$p!I*}b$z-)H>e_IBL6$`zVAGKC-bv{Dp>@GI{*HI$Ocb9;Xg1>t~9p!{5QA##e zZY>LvUVu}M)vN*>!2)w)?V32&=E7s~si+K;sMp z*)Duw+Gq}%pR98l85@}cFu3U*(H*tEsxFw9j+GCXLxDy-I4LglKjHlbZq=!gTDj>ffZl@W4vadhj-8DwhqjLyfZ6u5K{ukJnYS7A9O@00Ap`jtV%kfOvh21|9?QwSj8dHKPbIm{N42rI+kxCMACEdS) z6_8W?($?4r3p?}LeHbU6Hq)1}=}9~b*$n{Z`wMAGEPS27&sd?fIcr(==aqZ#NSuMf z8}Ag|VII!+*-@Bb?_fCmdgD#K|LJ9(6;)lg1ysy4Ff4I3pw%mvb^_Iu zS72vd%{g2^3%8_$R8f z04?g))`x)9j}OY~F9G77w?jLJljD4yq-l)U6&=&TSSEPHYewrRvipY;gL$my($)34 zRr4)~h{bP!-k0DC9SOHoS{-TjuN$)JNu(;bSX~+vdWQ_3%|eGq2b(1R;BV{hXOJ_X zsIT+mB<*{dywFS;o#Ef*G$A8J?HSH!T&_|@8I{(J9Cn>U{!m{PE1S*YezL39}A;09h*_DJ(+G7rr})O2l%-OD5jx1_>N2gWu)iP0dGg%OYi?vN*D+G?zP0Hd0) z)vSmsJnNYU9WS2}Ye&6T$v6BK?&i??9jeTcO0)8sPZ6)p%Fn5PrE~0!)7P1>tIQQMq*uDMCpomWF{3kBX z+j+Nfy7~oip?;Bu;<<@6z2a&SfvoiVIP;2o4~SjR_&wskcGvd3*NdhLIbJWSUrgkD zo%go({%YpGP&eVUF!g2aO^!&&U8R8sSN#Qy30&+oS61u|@)Xrgc8Aj7YA1X@>_dW# zj6%(npERaP%2Vl1l{K5*qL3nZ0eX=#7D`%$_QS*b@8P~r;!RLv32VeK3Z;bz$ugn~ncdqkW`%L3~TkQ5w{9F;wsel0(sYDZfS#Vc2%ghl3R$RjYuJh*P+kQY2D!ft zDwrvhDO(sPSRU=+m^kw=u#G+}o92pu0a~~S; zX&OoVZ*Jkk*s1O;y1r{RYhc3UDG_SK?J5C79{rwp74h{#(oK9rPwmnn5iWUX)#g|8 z9)F50N{s>6(YWnziAU2)iga_blXK_bZj_Lk@U@M6S1=|OhQC?;X_o$C^~-QuMvPD> zle8`1`X=@uLut6%x_EpDpHn&T7B?tOJl|>hflf(7)?(0oPVsDrJoa2BbMd#n)^XQE z^`yk{L4N0jf^1ZsACU1pKj?)E(bi8UQqzdA^o6m-OL}BZeG6Y<3=x&LVQHQAg;><2f{-FI0osc}G{-Mh7M?@6F@R4}FS-tv9^f(d0k5OuhX6UE=m z6&&7%SyQ$;^?_mCfn!D`Vl-~_QLWzvFa$OXA?{{Sr+GRv`sKf04{&NFh6fWetpc&ZLFq4v2tTSRJKY$t9su-yzwuK)`A7C41DqRhUc?R2u=#^(pfgfPdI_=?i&s zmFtn{Xf3lYCpkR6JzV&SnhKgbK`I+{|g_Nh?8JoK# zl|_^OwwMhK*&qCM53m%D-JmOo989?Vjc(vI;LNUFSy1da?xv1gm zpKjJyyMe?ri$Y2H&fz zCmet3fX=zd!ErqvK4xf4GnHr89>+axtvna_eW7QvavJM$Q|<#@{n_Bu&7(>oQIj-h zrx^1RrKlB&N*x{LorP~yiWjB~9=Xk>IhZbplg+f%YA!uPeAh*7#nw-_*g|_Q&KS?0qL~(!8{FmJ zsV~@k6?(z1AK3%Do6C1<=sFXJ(d5BB1|hQeAQ_L-t<;Z)=|y5s#fADSiajYEYoCQ= zGK*cCV`}`$ZI|v}sKo7scKSJf|99%Dt?HX?ivoh9UdK20RT;1m zb`91yFJ;gEiimZ$k(nzjj_5rcswyXEHI1E)*mEE&H zhDF#=MK(lTSsl8Jjs}j0B(kAHrt)*rzqe8l?tB(3h?!~`xiUIL*n0qw5i8j0O9jUT zPfk(asOCTEp2RLeuE@>f8zr&=rO4O|>h(l=Tn98p> zX;>Osb;v+9QES6EngdD0Ynk2{S^}MZLs!e3Z%zQFv0VjN-T?6{z2>x^QVnbdqyzB@!`b07Skf>yQ^uL zXAELmPohi$vIIt0vv100Hu3+3wqOEJZdVcEu)KsdS~5i~wi3ls8;jgCjqZ6MpwREA z4McicD8BBO_TG+c)Ym@Bpz8h!joWqMXM8y2eYZ#Hto*}qB6~%i4%_#p zoUVCwT zMT@Vyf+JQsKhY_@;e@jk)E>~Q&l=59Pf%}G!pvq_U)vg%b()f$(Z828%rhQHox?ZC zk-It9*@`HKU3cbRR|pvGS|-92?DL;Ts;s%cK-{~wxgZ6XNRrt4to9)ZxKX@-==CF; za^k}+FXmZexhcy@-H%og9C@@B9Ta)|M5%tcf>LziH5;R@tVepW&3QJwbv-7heL5`y z56PI#?reLXwtS&QGwE=m@fZ|G{;qPLOYYc6Fnnn9Fq3X|pxp#00Mghb?i04qai`am zds;Ko*=878!uo(&%C&a=TIL;?Md-7+Df!kpLA>rrsmF6i3K0VfAi+H#9jr8nc-6?r z^`imo6CBp1)R-ak6%6Q^@7zsTHn!#Dnc%;tE+R+-bH@2w7+-Uk8} zzqWJg&-I4E zn!95!G+v17rwXqprC=C+;D4Z~Of|=iee#5f$4$O%?sgmT=sxM^Q~ivGd#9jr%jr;7 z96&*X7a??T4r(7#b~KBl&hze%w4Su!jxZrZ1eG0mkHEwnaS^aQ~AojN)jYjUVs%8 zw^6Vd;+yahNtS0ifF09gwXWaxrG10BSi{X-o9l#RY_l7*=@h4gG1j5K0;?2;zOr1} zkh}UGDP~N3sVpKv#R9sY)^?5n8~M~h4E+DWjkW# zVJcqKaEt-vHO&i;!eg>t@>(t@oA8Q)oHF%Pa85swvn$Xtj=y)Fc*;+F)^!aqf*o01 z^TF!LPgoP@Xy3>e`=uv$$+g5JA;TSK%gR`gigYuyxHeAh5in+V-}@GNp*C-?ST>mo zdd^>4L-R9?Ik0n>GFu2+jC~>)W66zev+OHPE9~RByrc@i4##~4S zgQ1dMM`~NbNpCq|^48i&KO_tpx(v-uaj`8M`*uqvWP3bl0-{7OST*&59@-}B7@1OG z4J9hjn4K994W$9kX2%n@`Tj{u7 zQ(ypKuiuqPt?ZYYE$#`42rnrH=eScfCn8}8f-$z78AiqCq8ilp_DF~urT=KZY`Twj zCqCkiL%77qDLLl;J#5(PaK$}h+FPf%lPR)^l2jUm`g>Vs-qQ@C3lt=vPI*m~$K4LR zK$bhP!dLWknXIY1%{44BA9L%ib~yJp0n`4-8FBhq(2>Z(kQwwP*rW3 z2uG<9XyR^uorsl^_&lOc`r*g$Q4gpWXQDjwr}nX^gn#y)1#@3p{X#Q9!G%!7?eoKiyP&q`3k6-wTDqy+yrL8K1A z(72IayE(K|Bcls2beBywl)M{bL-RphdvI}sc&snu)xkI4fz5uO$jvCyx}-R`>QG4; z9bQoFv1lgf$8JC7+OnXrI-GHNDcgThv|wZTNl%hM#jBK&()L>|m{@CRouw*@L1DtZ z{K_Af5-V@g#!Zzy{vC<*=!k4F!gLx}a|WWI%{1PAYDPW)%DS2A$5i)!tKLOq|M|?I zAOWo@h6uhuA=!Vq09#SE9YgEYYj)6Hy}V6KpCv-Z5nD(v6beuVXE)U&#UHS!3(Uvt z)Q_rk9$Vxp4>hzvjxSrOw%$ND;p%h(u>GvyuyKH+>HB>K3V1a|d1A#y-F;OTDcJFI z_@-h)n3!-DAO#Ki$#BDW$+O!KvaEk?*^PFZH|7%)HO4`-_x%C?yU8x7usXp`NgLX| z8iv8lf~T82r!ST3m}WCFH_Ca(HWz1lMtR4r(%x)nIh+mEs(x3-v|b_V@Hl5)jgl%+B9I;8*CA# zPd^>yd}O|F+M>t)mW0TCbp!7Wu67%Iw2I)9>Zdc>JgFtIsCQJf=owsH3YTu6&xKfN zV#KHop17N(=ogmH+VrC5;_k-dlQznqZ!01FzIjc!fNq+viBN+jPzflv*ltH2p}u7a zK)UE7QakmlDnHYdO6^UVY^S~fny~)rg!vwigPXH4fi^(h;aU{Q2HgRGq6uR2{*Wdt z5ZOx)v;|i`CaZ6yI#J-Y8r4b^xbP_MFazcNx{IHf)nv%|lN@Cxr>_{q(#y@IgVBMA z*FxRMlW|2gA6XEVza3M=(V+T&zEy#(mNO>r{Zf&p_H>zQmQ{*Kpe`q?_pIm1b=I$e zZwoxR$fSeS@6D?W`Kq_l*WrJ+JOop*BS`*8^ieX$)w*9(H0*yEQSY9kc;suy!}W!? zQhAyVu&5|I?G2MWv{&HkO`;Xe6QyRGvu-D#EPG1W^5IuFIU<;n&Ls85aIWE9VC(ua zVrj=5l;Hn-{c)9Vv}gxuqHR!#QF-!Jg#t*)l)bN63|%jL5{*hTB^=}@@xjJYf6{(* zpXIi~Y2??|)9R5bH#ME!+f9;hij|z6_kLDE!S!0f{S(jl=nuXO*EHVP25XgG3MrLe z5A{|$-TaLz8_8H8xZMboVQkc4kCOj%y*g@Ds=$<;o+_jSETy`!rv>}j&n|Jay07_% z=|e2N{RXbAtGica-!;ZiYsaa?`+;M@UVm*gu-=A3ztX}CL&ieo9>a$E4ypdy0gtKE zs?}y0Mt@|AAB}iF`4Lk?TN*N+ZyIm{nl1M!vLRisqW5X?bpAkp{XT94+9os^9AjsD z;j)n0^ii@a@I+F#y8`&iUCRpmS&+MQJ|V+1DT;?&c7O1u(c_L~9ML-T2wG6G?jt?- zs3R^`>SW0pe`)pK)RMvKS5%FN72jwCA1q|OeT~NJqPA6rXPW<>#e_yFg~k^r_Es9;y4&J=y#;P| zGw7J zs^aa>m9gXws@E)ykb$+-qT{s!+;xhCu9a;~)5P z2gLkAV9V2Y(6S*qeeNW$(VPDAV~gB}CerwqYlhXl;Th~bUADmOWqGj*BKQo+4 zfwAC;V2fUAjnw8);v!OudVeBN=Rq&Bva|BT zyM|xi-tRH9EyOwPxOa#?EJ1vT4V*eIBfz3iUdG zd4r_B45|T9UdbtY`$OSq#T4okvN-gZN~_2pI9zbKi!^NM!_0JX)@fmmW#eZ9K188+ zw^TlqwA)2HT?~j)>Qq1}R4Fyz_1r_}7;P@;KVw%DdG1Z&ckWny>v~+8?AjFF{Gv+} z!ww}{TYT|oLgB}mz*MJweETh%l`ePGrFcZ^@@3y8(Ye$&JNFg_&>SopZ^Bns=Lw9%By0X+Tjooia32xGE@56L?Eh ziC+30HNt!6Xz}N(+uJS<`?8r}u1^cLmL|WtglipuO2a>zA zdxa)FggkXDomU`bDWEH9YW8p%1&z?c_g^{UqJm58_tcYa^9=t`TJwtR*=D_BvE5p# zz11J-yIu+h6JO<-iI3=$PJTu9^}Fk_PP4Vo!}neNfcKys`B{3K)$dbYL8*<|7oS3#Q>WLL87>I*x~(>w&~E8J}kK`BB%J=y$OJ3gYC;j|0*K~>n!e;T+` z@quSO6dK2(kONnG;{{ zkX>I{w2v2gIZ5cjkFyJqhhC7+EZ{iX%RG_qfYhH*6Rb4qi5W;VhPF$p*VrD006Loj*X zt`7D>w=QEznup;5Lc*-~1Uyfopb8NS8OZ zUM8}yl`1V6&RW4BLbcvR4RQ@SFz88Oqqht0yu=&kQ zgcl<5!xt*~E&5M~US$4UE#GQrHX_o zvK*JT4um57wRhCv&N~rec--X0U;`7v)HPTT!PsLybg>(d4O|evf^;!q)CCpa_RL;~ zu1yBqv}r)KmbQBbP9WvWwm`-2`L|Bw5O8P&S83jOpTX-qVIuz_h_yuvvbztBkTuHsEIL2@ z@F}o4^+M>FFv@$wcp&4Q>XsM!+iM8UXM>Az?i@|RZLQl)F3;FYc&R)9~4K)S9zw2R}ax%-;xSOB^bQcs)p_#2C>){e<`{k2=_y2A46( zo#7nSBy5om)9KEFxad6TJ85^&Q@!#v;C!-v%WDWsfcC8)2kydsMUTZtTLoGLl}Gxx zGE>}7Tnerxn-yhoddzh5gsXEz1=*s5d!W$FQ^Qu}9Cevnw7lzwv5Hw;-lFblCkTdo0t5^V@FsEa}c(K zR-`@T2V6(uC7DTtTrDD2JcL_-RJ5<764)p|70$dAlO7o4(ZBwIS2<&Y(L>Z>xNR9~ zuw?T_i#h0k}y|QQqPmI0<-IH@p8hxpvk83Xu zbeOzRWJs6x$k*QciN`%dTk2h7j^Bz|QR@qt1hPg%#4$Jv6g-)ncLNXp+~|q`QdLk> z<~RS_tb_&GVAGojKe%zx_QCp8C+76!R&~yCMfrSGOz#i&WvqnKe&#|q$=m2oa}s81 z2~{k)mi%leW`EFS5sb2qJn_Zt-Avq%wBvRAs3m(RA6++yde|YJ zlI{1I52zW3t!>4wd^?{JEA~kgJVualSYlsqXDPp3At`TM%xosE5v~yXY+oW-hE8G$ z026b=LVbp#7uQiz<(q0fU`bw{y2CvE9PnTh`;a)z|m7(v;<9*{hgP z^D7zlWAV5|^>%?t^5@rAFNIqu#$1XlZN-IV1oe|mv0AU`U_G@bbAJCSey5yhsoi$- zF=ykmwed)OkVIU2sGZgbmosu_NC%odx83?<$rQDtjgG_or^q$*xoDu_EDl%UkqAEo zOoP_l+-pFYG0kzftnj13Ck$}b>j?!=qPIuIx>J-}KYUQCmlr}mGtgk;^Y)uq|7)*) z_z93xKQZNzBx@u;5&dVc^SVMJO~3x5bnWk1iIc*-@hgdM*yE%s!$tk|JFU?pH68YH zPrTaoAd?bmWvO;H3We zSn)sYo~YY!jFn}a9c%x>Wgm0oB@a7(e7H7dD@mr-n53Ovris0$+V1bH(#J;tfVx4R zzHa&H#9d=;0`*BuW>rLqY{LyVrQthAXxvA>mK5EIJ#0Yc+9CZsVV&$8iral)BDSOP zJ`!Wa%}4v@&WwKTjQ&gijD^|ENUQ}iapY45j9rk#kf{rsl!upUd=$}`2 zX+~dkRh;pK4Bj27brEOJd93!C%_mSLYKxu$LXu5;zGT!+az+;iFOf8~$`Zwqf6_Hk z{L`*eF*ctcj=?0h*7;=p$cy$7^3^yciK{kxUFK(U$zLz$y^fI2Bg3v)7+n+|dk95& zHQA>??$Hkk6|b*^nL|Mx4i+9+bD#+-wSE{FY3Xag4P2bzX7Cm^d}eY~JSE_qe%^8X z(_ycEL~H~r?{uK_nvpOns?BU8krj||l8YxCr2g!?E;Wc0HY^f#W`9#iK(I~rOOU^$ zUl2Qmp>egt>10I8XOlH5<1aJQUtp|aBV4>%E49blL5nqQo%#!K&UxVdhaMk00h%4^ve*li}J?vKTi`lAlg^B^rFz_^EqMI zjx_H3K>vK{^UyQHN{gn{Bc&C8p79DNtUBvCCzHQN1%iX;hTfgjCZ*B^8aHK!+Tjr! zZfc_ojQyvvZsGzc3bK`8rA^pBC6*j5;V8Hat>;eKxJm9`UN&R34#siF**|?Zm2^As zn7d`&jP9D&D9z%pK;77{l_@#c z`l(o?NYFciIm5)q=*JirtalWiKPnp?Lb*`8%V(kGg5;(4(>+PXjl;~idy$l_gJ!zA7o}B{P%L)I&Py9bI?e!JuJ5z#Jz>%3!dY4Mj|^ejoKX{ zz5zi)$N$X?pi@nb9u=oyy;c8MAQsn>s$OXxcpmKIc2sH?D&a97@DJ|*_t$ez@+i#ZvgF9AOT1RlZJHY>2Z0FdkPgCe{nK!d*i|@ za6=4Tw6I%Kd67ge^?J<90ke^Q>+f~70zA~WHxRoWb*02z$4xQ9+B!Rr7|etU>jO$` ziC9TyTmH~{7e4>PXPCl$oX=C4@=M*$zVq$%#nyRay38koIs3*Gu_3DMS$8g)jgl5U zx>Lmfo0RT$P-X+Uy7eYQFp+1n)BNYeeLF#}3I1&vOXL09zgBbwc-ggW@(m-G-x4Or zpej%ap*>+jzHY%^?xSE)(^H(W{SS!K3pvCAT6gco@i!oc>olygI?+sf>cpQ0GOq%3 zv9xi2-z_zXHFhbmbp#i7G`J9_~5W#rQr`zJ&JAaINfCi{}@I@jeQ*0TeVBcEvNYCDMMrEfXX{OCV!sO zCa|EtlVbhsD;y&|FJqVT^1Dk?Zz6L=OE z0T@%{Io&fAR*?;_7(M`CR?EpETKt@U4=C)KJbhV?L-gD_0lSzZ8wS(Z`2{dxT$A)} zbE87Nrcayh92u`O!Q;e8B4w{1mvw|QBu_wSnAQ1cII3?5rGEDma;c$EKO{0)_J8Fx zJx|)psL;FSwL!Q3@?`1U-%u8(i#d(wFMKRcuGLE1Kgw%oBYRZIPC0i8o2eF5d#*r- z(hED#_oPsp^4R8)7XoYA*n8^ou@P?yN}J)eeN%?`9S~3TI}l32-%N}K`zg34LhzVM zWGDv&&U9!A93X3qa+oREiKcPK;0dNG};~??Hwx_kIWifo%vPsHk8B_hu{@@&nEP_J{(o+wF02I#O^AyC5|g3EKMSISZc9ANCGY>ahQ!#Z zxk!SnPo6$YSWbTbCf5_K^@Oc-Z~qm~`(!h}49fr8JW)CFd8AZby4BSuOu+&0zzM(F zH1JzNn%yR1lt3?VCynA%n*1+Erc#7hAB*9j4)ro`4MMJC_F$(|v{P3*JlTnnSXA&o zQZPyR1DBzHgN+t*nwr1xIT!gH2k^&yjN$EI(V{;(xW7&X{{JYgy?b#rN^(p(IzBPk#nNwd9@SINtlv5j;wUjk&5>h zG+OGXY1}thA6KX^o4ZU6_{O3)fTtZ$LmB6X|`ww4n62Ch|A9x(3#CeNOrrmm5 zQIaH897&lC`6n2M{P7V7Nm4WTyz?f&+Ro#R1NF7gkhF(6J4Mi< zIe6?(?86~Ch2r&!%0J1^&O`nKPIa}o7+Uy8`GgL6;(0UV4F}0o3UkuG!U5REeaf7? zm7oD1jFWq^Gso|W9Yszqjz!#hi*|{;0l4$~y+ENjX6Ov~_?opkm4-%Z((aNnFldZ)x4%BL;)&HIZ%n9EU^?0!=o0$vhkyE z`F%j>NcW8{ssK9)u=46|1-*(rc!L%JTlo7A7ohaB#h%k<`?H+mXwNkS7`6P(6GCsm ze$PA5Q!5KU?@XhiDHek|e;xaxGmnvXTlq5tv(YS(Yl8_0b0>G1HhTGb;4(!@b+8Cn zg}T|!mEgcFF#Z{QjOYUm%MAIbpI$mdiQ2rsIVQ7xNEehdkZ`!!9gO|o)Yrnr{5q^$ zF^oL#U<>qRQUL;bjucGJZELUdK4-}89Uo~mJxZ%Sz)JsMCDFXLB>|I$9PBE-jQrb zPWGrYD(iAh^lbZG8)%_riL0^|Ti-QP8-Ww#+&QFZ3#Kd*LN?h{k>n`@5AsX2J_E#J7Zx zLUQSTk#Umq=hKb6!b1`A{bZpFd6)Ww9rpe`ylfazIK2*H=M#b+WSmbZ`pmySxVlf- z;;#FBAcp14y=`#2^75nITOhQjfobh)WTpqc!t5fOLpnRb`x8P*f8t87{{5NM)bJyd zSaIvr%(Gam#W_lNM(MK8217XX?+-oE-J%CruylYJ;u1qT3*Byc#fZvX#m8MKWw_S?{kxLnR+C!B0vJ@BX?d(OG$sguGl^o<&@%l0Bgy%&JOATUz zZ@I-QzIo;s8B#BhS^#;1qwGJb0jkJ^wXKh3it9Ine|q1_6zD0Fq9^gOx?@q_WiCy; zx;mg*1cf=W@D~}T!x|$Dy9qu|pK!|;8^jD<0j1NMZ--9km+uE(1|dnD#B`Djg7VZd_&Mf<%`B ztQBxEb-4T*@`p!w+nfxx>0mJzZg{E)u?dyfXy7cv0YYFH;x4l!P+!3ae!f2`G_{so3iYl#RV3tdsYug` z3M+_`Bgm|#)@h_4MSJNOtpS>v5`~&qbC5BGSEB;FD^A`&>leS=wARvC?t8x<& z|JLS45TjMNJHhCq8IUB@JM6Z+1o+0%1~5kL+(+-QC>|jm{{17I-tjU>50IesyIX`b zKH$m+@RdFSnZ5+10~)ff(zn>z9&hw?<%P34B711S>@6HyKw8kby70C^X#;r}A}cjx z!x=)B9~e-A2h|L;8+gmSOg~ZW@m7OZrH3NNkb8;f-&aL#@#j^^{qL)iH|#V&&O5`C zvH$(^W9ff%4UEC=cz24|I7QQHfO@>UERYYx1~8!pcw7&y2-*sxDfZ*!%*w-CV4wQ=_( zzyYD*^7h0EfZ%TT-<)F4&qkl~-!D$iKf&QJDR+|}v#8~3ekknY4v>5$s*S#P-k-15 zSLpH~#9Eg7WG~lDoT^uLd<9AB=(P*|nGTls(I|@f8)%#X$kv*k*r+zH!8omC z_h-Pwysar*lf#inWU;t!uYGDv(V`hy4TTxD)^@IIF`}zY1_ULPHh1A7k({a~EXjV1 zJN4y4fkq}+&;#D~VC#?qgQB3mbiMPN!DdHxs>g3Af|(Z2CB6p&rn4DKGj*0FSj!tr zC+oCHM=yY)|MElGy-Eu>!)tK%dI)i8zM5Kp(>{4DL6wbMvGCGfiGQ{ewyt%eo$T|| zkIj}%en+zAFBh9%GyIt*%$NjqJC1?Gr?TgARQB05{R)V8IA#=+kL53S2q~EZktN%E zjPJF(h~>-e>W63b@7mJMT%J|bdI;ja`;hFJOO=5}W|;gA4r{`bb?Nq$^ktiJFj7kc zKJd%Hlb64k3N(Iu0;4F9Ig?$O<&N_p<%?4w`{p@J;GP8YmzMO77r8NQyi}rBZgTvMJ9MBH^0~-YVQ1=%P_WW>;()s zq@@jP%8HX6kWu-7`wl|?GkKj!|MXe$=3Q!eBts$D4y!5WB^6y^P6HwY+Yacm934}c2!ZRyAc*7Wp_bR`8pbF zwZoBYgN{m8SJ;oJ)goL)1fU0L$nLO67U{hg-cxHqG`P&QL>N>&4jNd;&2_|%ATOY{ zX=?WS{>7mZnzl4=*>e#{w8cEfgbyIrhgE+8I|We`sJFhL(Fv$GwRH_*wf4eTT?IwT z+rtjD9{asY&0xmP8N_wr%)$&U4;knd8dWt^K>PYAP**6P(;3L2R5jNE4irD*Nf*Jt z2-g6Dr7t}hdutHckT0|N+1nTA`(BXhevksOVyV|`O$mEX0XlxpdWMGx)RsG_nm_zW zf5DIUW+#Rszwq?FH}ZUT+Iy2HPGCgn%%nd1ZL0Xh@T)&pBO~+FWPJN1Mwl|oaV+;h z;b~`CK5=#3Qs7(EEnT^-Axf}$J`Oqpu9Haij%Fr;Et*+JYz`DKdqfkZ&eS_Q+!D!b z#C7HtxMjl7Q!UCT@9_dY=!ORjzUE#fYo{3?D1xV@7Qn+Z7`aAN%$qi^bwv2#Q?p>A z-u7O7uATIz6W!U%lVwhS@9a2jI8Sy7_RB+D|KjqIuwjfwujJLbgiTkqsb&PxTAzPq z#6G4p444TOiO+T%^UGw>6kh>ZFS(o(F+T4Vr9;}4*fC86^x4N+U`&n|uoB0Hioh$n z+R_vv3JiR3(SkM5^o}$PMn3TlFnKiXUDp*i=z7#^A;aFtGNP0f$X}smsq%i?fiDN! zk9tdKAFe3K+FuvR-93HhMyYW{y2xr`H(6ZH`Ke;7pTEIJ_KzIk8XsC&d2FKOX|J7M z{Q0d?I}&gOgpiwwMm8u)=6=@sxbxxIQ@m8qZ8&`;w0F3_)XyfZ(N5=scfv*1xXBYK z*We!StEsA1iFhLsTn~n9Hdi8`rEsI&q6!eLIxvxT& z6O+dcyRam@AvbF!&?Jw&`6R<7X~mWm-;@RmoR=IhNHScPetftk1*!#~i)LlEf0nTc z2?|^{%61fMe;x<74?ecy(L@JtNbI4rP>sXJqC_mHxC)>VO2cM)A1W?Vt(W81Fj8j2 zZ1{*>AP7@E8#k;B;2iu_Pq~r;6MxXN_kA8N??c)Mbf`D8_MG3pylAdraxgBKO#LV^ z%)IHR)pw{gQc+4<3->-c7v=LZk|}hJ_CgGGL&nfM zy=JH@XD%0$l%24$IQ5EilKkZ^dJhBQta0V+Fk(KUzQyA}aF-Y%a2FT-xk2foQ2I`& z+WH?nE*=#}t3gfSqfLHZA~*x3=$i^mq;(2dF+^UO`BGbmvbT>RLD;OO+%j2MWKV?f zj1PEsRG<;CNV0{}`BfMnJp_DrpJV&Z_ASrRI@nZ(Ns@Hta@)nrKL|4y--;5bJc6dr zHht?6KsoBYQD&n*>~QGJK)24WU|9F>&Blwiug30QvvR*3elyL4M?wC)(mpUl&^wE+ zb>CgJ{{QobJ>h%PuDgo0Gwg3r9@JmFkUt}4Bw2)mCI zbstHloJP>Exh5AaAAgBEqt`yx1Zm58IB7{4dD&oGNAHVjL-GbR!7I!>iQlNFk19I% zwGu`+JxgR+8_%Xs`ev14oK${2QB2qT;~SOgDC&@2XZ3Ga>SX0ftJKUdC;se{y&E8bok0 zRnb`ZgQ)J*`WUo9S9d|woK!D;2b-(_y%r56e$;PMgjW{kt~bnuf65We8}LGNZ*iyj z+)E8hhABjS=*^VzLiTc8;~GJ|0+WhC*E4QQaS}C7yvWxh#9xdKbP7~Dw>pdf&cA9@ zqjW4o;E${6<{yiE%l#z03~C(zfgXYdcL+G0yvK)pK2(NVn@L9)hT-Uf;4P5`ExsuP zJo34<|1C+9SUH5VMN8t=te}{4!Th8$q)F>EchJoflS)0|Uw;5(>>Fs>$3NgVM;5>6 zfxGuu8pkCY`JsyJX%={Pj<01!yrhnc)_K6H$%WK=Xh`_aZhQz~?wck*#WXdpZTr!> z{Z#mSyS#d0SxBHjhr;B`tG~#4&kVn%TMucUW}_z9tW zR)Z+S`f-JpGf#!ClD6y8acI-%UBu8N()(d+ui=+e<+~l#b!gl+GNb}Eg{)df1;GUt zae~mqcf*P^!(WTy1!q+|r`wkX53q}x_!g1B|B4$Q8UNkZmJsyS?I6M(-awe>14i57 zY_i;)B2B&%ZQREss&~CN@77)3Pa`r-U0WusfibE5UF@<>zpyUY^Syik#a?PhLCLbw@+t*2GQSxnfwkdG{v-kEk42kT-`O z%l-cKYRRBfpUa@ert6C_D{<`q5cM9=SpV<;c%(wZZ7Z_(jO@McvUA&8k%a8MN4Byz zEh~FvuObveMwAsYqUcfEYx-~a!d&gqb_sE=eVxN^%$A?e3Bt%h1_C}F&vAd zZ+h(Owf>DRGT|{2-NyvI=P|0gr6a5_vL;MFG9-N5>kf(Px8Wao=LrtaD)3r})S3YV z8GFz2&uB~gY}>pphnLZfbvkZY5*1NHq`l_Kz1cu~;L5)_!iLeicJWq#_9H$a{K>0A zLXPRm0{58a*tZ{Bog!cFOnROxf_{K8ndS2T6s8m*t&S&;0huO$87E%_Zs2Q`vq~CM z=RVAew7du|GDA6Jwieg;NsVcpt;X*nCY%JPGdgNizvO$TAkB*FYzeT;KSJ;rcdlE# zSqDDi|B!Lh?R%^E>CqMf3LQL7-u0r~;jZh^7-@~N-5r}7;PA@Ot2N;MJI}W*<$wDPf zs^*R2QEwEAlP-KHq_4usOy!6ZOOZEvbJNXL1xnIzJmI(Js53vy%&i5^wVI^TFe^4` zw_hqr=f>`&a9_Q6Cw35T!OUUqal+-oLe2lqLwVX|c(;*(5hZKmVaTGmn)(gL!(<5K9 zdea9BV4wCDcv;9n>86c@0R-f8L?BB5C=rC5?`f^yvDX%~I%x=4r4v|l<|uMX=z+K; zgT0mt4CYk8HnSg4EuHTym$Vdp8Ir!RiT`-+HAX+`yIq`+iLq14Bs-7_o;#mjUR!l@w z=7*?$#1wF>*52N2!tt)5&MepIFQPnzBVfhCnDiJvPT*IfeJB&pNM!yeTQvVv+@LW+ zfUjFg9J<^CmL?<3h}|0qPnC~+!HWvKrv;Imj0KR}ac%rSAc zj8qaLu=-adn|LlIocx0+UiqTH;O#TG8o16iR{_DOoB6?4;rQ#0H^d~nSQYz1zGD&M z!O>gr_N6tT`($Gq+MkfZoK_QdsfBbO2WQ;4&c$=p5xDz|(-I?$vDMKSRxu(Q5^+(fy~spGutbjMSyy-w2iVh_meRb2s^_bXUMtf--A zm^88?&KBr}tuf+JR6B#bxBX5n30O67WfW)~J8H1OLmI@HaHoa3wGD9B?P#K4!yKjz z(Djk>PM`CH42@jf2qol9OFp+421=pCWt!O%SQ~=7dq}N^pJ^1S3XMF}EC?Zn=@0M=80|3Cr{X+K> zrQ1U&5D1~_Jp&^pfCWf~xC&SiAmc*war)hKanH)* zd-Sn*SiYCo6;)y3zWdBEF`ITJD-_Zs3@u&GCRr2Uo3H=~el;y($_=tsOVf1QACKci(r#LOzUVBu8q49!Rnz4!MY0uL^K(tIFHN$2DFz~EvboFTg0R~|LbNA(3} zFNkhqcMYJ13T{2f`grTwFG~?J9mOBcy?@1$GX>pxJejNB1P(VU|8`f1D>ET>`#QvI zAr)S4jdX0A1N7n}*Dvq!*smX@4wqFqB4c`RvaDRJr?ji1(|P86GmEFa5CE?RQqTIe z*6o9ual5Eo^LE~6f0o(aX3`Vt=36$30tq#i4UTJ{_=JBk_te>$u|?>oNgd)!wV>I< zF0qEPM^+|aIO6-Gt&1ZFlnN-0eTTu()t(iXU_-s5SCH$vt9q+;9e@bdyofb5fUPK# z@FS&Z@t~yYXq$zEfvenNGPt$t%7$}C#KD9ZN_nVmGWTWn219OMS^>!|Ei#2XFb`!l z0}y|={&Js4_$`m*pwF^r6-9Ul-j~uV$5kw?Kx(?)Q%;-Vnw_VKRu;Lc=_@71|rVh1K~< z0$ESd z5#`n%^;Kg>^VQi3ONGTaZ|>6E#uX_w)fi!=U6vQar7aKNE(50to4fv}MMCj19A>O; z*z=?|8|aMfa39Rw>G@eWXArxmDtl#ZD1QHfnr4@QOPKWEGsUuF7|tSGd)mi1S%3lE z@E&7WETN5#97`m_`eMM5QyqfOLO0z`;M3%`V&Hgozh)tj*z%jUq_g;rdi=JMsb+7( zndCvHyhm?|5F(-4cCaQG#AQD*kfow_d}|HXbDj_`&V`SomqRE2U7j5@JX7O&dUKwf z0GMV7>JN}(mjV1I7)mfhf?Wu?Z#Ohpi4e0+Roi_q`%eYMg<%{;zc;9#?rlLOGR9{o zWrDfx52ay$FL;aEjmvrRiPF-46p1<|ZW6DCe5oI&TiCpPM&TbH^T^OlZawt#hgnrG zxEGq!bH5aETGfK1PyT5DHBSz;WkjvUZNA2xaVIPWMv4tA6|_8U7!KofH=U6-*IA)c zNjK7_+S6RU1BUI%4!^N+Oy>|AgMSyso0*o$UNcP{dKcD(eShGl73Wd(SnaBHJ}x8D zwal=D4(5>hT>&B(?tjDvYoI;0USgvPMZ|gu-sXB1C+=TlGvtF zLn6C_R17xw;0QB%-9D= z$KMiRv6*1_OEzpI>Qr&IK+lTzAKC5iZcz9h?~D@Jk$w!;p+vt9z(HBkc{w36 zO8vLRuxzG$AO%RL4!x``|Hja^I?0z>93llc$`9e@HXq+ON_Gi@(7ETiH&vLgWq_1K z1dLo)YU*5(iw2VWI*4o&L#7AVT=6E2xTTpWqNhR6~aiYbF@bVncMOBlXuUL z`JO)|OFkxL*DAL+lK`&E0+iiVrV|nS{1J&;p@58}i7|iAG^eEQgqreMcA+FX0$Mc8 z4cndnHHT+VY2`h5xs_?N+;Y~paLAi(z152N@#<+I2B%Fvz_JmyT0uw;yby?tf2Hv( z#(Q8$LKIRyzcXmR*ENgykpi}sa=Z^4rbbGfV>i^h<;&LW{yrcFwo0As+J)a!{D-cN z^~c!!0<$Qa5R+2XjUBpcjSJ~EN{$Nd?~%bLE%t-6$HBlhT2ij!yuBq+mfdkymSfSK%XFF&G zMi%arj=$upAgdYmsaUw|)TGz56X*+bZP!N!oAbLp!lwB>PUD-q02~e828`c`=4K&0 z@7Llu3Zr4?hR~^+P03*iHBkBEvIMf`)LvWsT%b#jx`M6beY7VG#e$dGrUq5Nu7?%E zvjvSC<2pQgJwmJ4;G8NeP}mFFGPIRL>0`K824yQ5QPS?&iw{JK(d%-vnZB&_qa`1D zjRh2NzCh)6yUc&RIqsj%qXevhJ6S@)MBhSbLn&KD=hdumn$4 z${#j8cYhWwzNwJ$=>#f>&mKNU{K34!f6G6bp?_E|_PtOAJA|VrFKhYWS{a~O5SKEk zAT#yoNw2N5l>p~X9j#A}EAoa&o}5IDrY#SkHEgg`r>;@1AcTPPNKJoEH3JUZ;81Cj z)gjs2dduOsIL`uzIW~;WZ+H)b`(%Fqxt;&1<^PA$)6yWttE_&h;X$h3SQu_%Ou$6# z;IF%Ouz>t05IhIC*^@|BcM|=T6$4SdLTB@Npiv0`r8bh3?!x#5a-;i0MIE1@&n>pm zuJnKksTbz9_o3r>gx1+;ZE>(Md*cY4fL-&=*N6wWASf_+FjNEhw$BJ~9^tw<^eO2U z%fH-(!*nom7-ln*i2)V2fKyZBx!!uoHpBR<)Mg{gWvUp&?Q06;&m6^O{^5@0xVsB6 z_kIL0UYKs%pMpLTX(}r;plGcXflAx_y+545f~Q9?IDM(5-jON^ih02`ar<@@GE6_F zG!vni0Hx)wY8ogeK1LoHR6TxxxC>v8ztcBtKbNAur6Guk5x{f31??XtY~PHl?`G@!-qQ2Ovfig9X;F9>S?KPozn z|Nk@tKr7_zP`smDYS_X5{M!gCaqPe3_XGZL=X?Q*o4)Lqw&WZtDgkS)0wpATbL)*a zT4*B#wG}HjIWI{A7u$7Sv*3D21Xb;SDWUvL(fIUm^!?wT-T(>%Im>djdC%mjaQJ?| z|B3k&+-<=(=~t-h2aIV`Wu-?d%R4<5fi=K7E$%yd!Z(RfJ+am~Ed~yJw6w^d#KT5XM6DD+Lyik~G;{97GnMT^+ zApY);PJh2wFyYuGNDOM2%YMz*cf8_ z0aHIz%q1qhBjmb%Jw`$zXdQ+-mwwLdDM%2y1z1L3Yrn@0M)=}Pm%tkXrRL$m>P$vwlZUVdR4{ohhz**cGpFRZiX&xN`b31WPa; zqF6f&Nu5IyHpA)Q!I{4ZK~d4Q$ok9%`4yWqk0GNHaC0qcZ#m1kcX+vp>+!fB{8}{{ z#0Lb&6liB5-tH|?n{oO5K+-l585Fj#$BbD=%b#yWmioe%N}z6>GJ+s1re)Fn>8C67 z)V_0<$Wl!G>Pbmwt|i$`X9Y`tsrTi56kg>({SSJ`D{Oo-eH5atMBMt@#CO8~#n&g+ zqfN^wubXk7wDfQ{wzoUs22qe3P2S*td_P2H>NgODExaHBKo2no^Zw$e((Hg3;3>I^ zQT{~+^@cqEEKGzk)Jxce4G5iOX;w{7QWIWpz;)+Nj*+0tS%ruTlhcUOFi^!qzQ@%^ zpsrvjWSfE3Ai_0}Tx1HDPYw`iyXkV20QGQ^r?sBta#veOkI}sI=3|c(t1UY}F_?>N zss{YJg}ZqEaHX97K+yIqmdB_dpHvH_X*R+2w5~BLghTs@ky^Cb>K%} zkpTj={C~fu{m;{~bHW2n?LlI4J?n-HlntQoW=r%J_GJ#+Q$(t~}_Ixped4 z1yQ6fZ~YNLVso@A&xIR@8marBil4$5By^RKctgF7vhHD=b&PZ>Kd`ttJ|pgEe}8&N zw*XDQQ?RulGRzpaEmIwroSiBYS6;sADzB~&zHqQ&@ZMSu}}1O6USOoMc=BUE$R zW5nkP$&M5i6{i(KQCBwZ>CedfKI1Cbj=vzwF{U~_K|-UZusF!dTofiqm&MRAhve){ zenMTKr)C6e15vTN&2d-VxSN?}5xQp@f=)-%%}Pgkw&q_!ModOeLiW9?0}$EXE86Q z-Ow=Du9~{~63xhNsK^WZ|HLTS5%g(&SUwJcpwo!SAo++ByyqU!~x#fIL`)Ra$k*GHC?2eS*&Fa^5+DTc}rvpf57lp}9?_=YrL^ zp0pTnPJbVFOo>2a9tKim0i!4xN3=U9&QAQZ}TIU=S|I5AVH`q&8ItDDVzituj z_xuhsimx0q?!0zRXj5DU*m6&s$&76Q$7ni%6QyemNfSE1w*lBqW)H=U<+Z#fTw5XU zT7MAwi!4Z%Jjd4M7s)F@KFYsF|0r~YOdKes{Cu8FHIl>>e4zW>)_R$RqupRT<3LXA zIK0|}BY`A5e7llsWV2>6SFzo-1h~B;wwGtfxLr18KWq6$pNiwlGV!t@pp6S?=b}J6 zhfpCZ9F7Phe^q4z&ik1s@bzTl#S)2wn^#v}F^BI3NDr@IA} z{+MOhf6x*aj)Jz@BchjaTjJ@Kn|>o|?f1@hrG{s8RRS!*FiIuxnv7^otBuv$!V5#8k z5F*gB$xTSJ7jO-Ww$FU({u4#wG*0cjT2Aa+!S{jB!(qX7uR&Gl(ytJ$ zd5gswQ{aQRW^P_&le$De{baoVyzmJZ$Npx7bnI?2(+EA9DcbbNqr+g{v5EcN14kPA zhIZZ+$mywaCcXG$td=a3C`SJK&(Fyo94{EuEzq=ja023wc;pMf_BmieRe4ji7*>=s z@ml&V2JSLrr=cABWxorK^UPWdzLd2mwg4x}I%w;-{;d84uM8N|<;oI7?VfckfpqIo z)*%7cy-1NNNw8>P_EJ?Bj0SGmYRMs|?rREIJETHNCWN1VHD{#i>{ye16fS&@P=nQ6 z3V!Xb6@19J7Vfz_;oP5kTeC1?76&OFVnCMVo7Um^`!obOKw9Z;?ZDvorXYSJNAKi8p{_Js^QAkzKG|^ z+{V@bC^l;RQ=OAexpFb61j0620b~`|!5N@4y#r^*-G94GrfLTo-I>3BZi*V`iasLt zm3+{KGk$GQa~0q@ecv9%*%FmIIs3JEV{Mij#M%Ui?hNLhG=Cm?n_bz*lfCh&ZAksH zJnefN6eUV{@nJl>#CVD8%D@5b_(SbixDQ_iOx#xHdtT@fwdf+=;{z@JUuWu<;K}L3xBX;>8_NLA zqoit^5N@x{24=X9G+OG#FXA@tc1ep|8ke1~lGHD&|0DD;6}sD*MI5RXwu3@KoOw!# z+1hLzIZ513P`E)3>RT7FCG_aN+z@qnoaTI`MSQ)D>r4F;PoWPTm&wE_5Jfx8MOAga zi&PM4yyFidn==vob+otQmk2&>er_B1|sE0X5%nT=bQAA|2#iTz?T4;w}8ijuX z{LDE$Y*!AZfHVeEgDl_J7rUNF6d%Hc@K+?wMqJH*O0U_g+I4$+qN!JK{NdF4mD)L@ zK8Z{AInFPXSx{Q1P`(QG7SVentAV;l#l~q=Ez>QCmb$Bo2GK^nKEiR4WR;Tp21f$p zhubNy!=<)Iy7Xp|R6Aele6 zfmWPheYHZn(!tKaCz>{F+lSjB;1KD5hH&Gp2^>jfyrjvTjbl5{oO^W1UMX&bqrPO= z-THCz0u^2rBkW6Y8gPY|ggzI*Qa zqzpLu<4UomqhyQ-^oL6bdI5%!wH#gf-^r}sFS_%3@a1i^F$)nuyZs1S)MCDV#U?AcgNL#_!5HECfsr_d zy9RfD++V~Af=<}I%_T7$+tZndkfwlmGE-&bdN;!d+;}~XSLElxrCU)<_+LDv5?4sC zcReivhr>}(jz12pHGv>Jkg&Weo_@B`kTX-8FlV0!{gi% zqmPPVU(UA}g^DfyI_cUWN>LkR3FCz&^Ecn?09xMf6&w757fJU4?e>Xh(~KsKwr zp~GBUb*8hHPdkUrJ%aC1|I(EhuP#fRa@ZYSuL^Q*-|em61C*!BWl)e_T^NuJrbiHW z2PqXdG#V=$jC8!jt%1A~s;a0^SLHvI?l?@la#Ls;hroXJg#b#**mFK<*BM8NGnSd? zsfaF1upDmqV8p|=TsXD|^OWQh(Ma+;6{KJ07E<#+j&*fs=RoOSh04t!n}MAkQPBOl zmc;7thJJ;nl%*Y+e*W&-kZx*U{DDtZj1p*;p7(4ub3B56RFIVIRiil_sd!(7Fjd1JCW4A4*@gWTk+rx^@;4koMf=me_EhAA zBA%K@4Nhw3NZ;RF6gFb4fAlMI>1yf9cEoU{QEgqG!+8rTJ{O2>!Y&mf<<2^$Y15 zB^FpaAkksnaL;_Nx4wH(O%2yZkM#}};>2-dqV6%d6ldq)wXyE313Z>YlydDN)f+tp z=8kNk{HG*-aC%q!N8cMFf2D!q-cCcCA9j)B1!?I9yUV0iZfDe}Bc%EodM>i`<{-w* zdk(s^6DRvlP5_P=gc11t{srL6)ul4r!#ZS~Vzj<-M5K!MDW)G~vGaT2Blq?@k7IyK z4Cn@-)VJ5vX{ZCy_?63laDtdpT4E*X`o<6f6>MG0A2W66>91&-+4p)CkE6q{vG8=B z-xI*OcJyNR6Hg|HwEk68Mg7g-ajXI<{n!$A>lxUQ)Fn+$>Za zvl7D>K`_RD7o8NW+)Vj17BMW%yyp0ZaRq#fZ#!|{9Y#xJ4oMx%5qlrIwHbHQpUfV0 z3xr9hX8!hCoph&9Dci4clyFvy_Fk=jOB&d5sn5va{>EDXe=1_?7o4s}k?+%Y&Qgcc zlrl^_{V+KBmXVURRJqQIaJW_EmE_0o7qBJd4UM7*pR55|@J9Rt(-eMZIo~yT^x z>KyW~zasa{Htu7DS(SzgZ}8wCel!O9cxjw06!w|!3b)Ag zh(Moud}7$W4cU4`Q9mtuIdM!li$z&j7iYCb%r*h!GK(6+jYk>I5QUt-9yl}v!GDkS z?z=bV5 z>y!(x;JDY-uQx^^aGLn~hx3X;cQY?I+ZS@-=;n;byCgjeb2fSqcr)&LkR-N@UZrP9 z>g#*2B$=q1_$)4wx6sn#&aJ%MuQHpu_A63uxfgsNKM`zxPKg61peDiroWO^qOxqXi zgdR>W%kdC$Eba6$|WFYWPU8@em7oN8e7g#$9y+lJn9R*$-Gg_x{ze%{iHuA zdKQf;uczCUxaEY4L^(`uZ1@MqP{P%W(gi=n4Qvj)%`|F3#U?^9bP-1t*IuNIVRk+} zEP>RFzwcM(DVr`xp}cM7=Ztk?xxb5uFgt(y3%-8M%pJ8G0D1C)cVhJ(%|wF3^BJSQ zW?6k1F~UGPExBiE(`uoAm;HbC7~!h9V8uU7cE*0XhAsZeawTZdrfHoE3*rJY4A=k()PtYt*nkY0 za$*f{^1w}m@%h9{_*zB&m!Jw|4oE;WZ1ji_Baa&7M)A(H2WFE9{ossra-M_?hd=j8 z*0M<7TapZb7ya54g*SNvF z+)V5cw~P1b8r3`8i3Xxvf7!YDu^aE}B8rBAlzpX?rOxF;zy))%c?1M;{!AC9m&}P` z&~u8W$HhW1)!(N(LRbr&2zp1}<347^(kT2=vHbJNS2+TGOVSCnQR8P8e?&G=Wt!tP z0q03CkSnyz$bGELeDt2|MHW(+kEu}pI$uGaRknZs4fQ3Vn$`!;j%RMo7~k5nJAbMD zT;dyF6HFRM3Z9tJBZRI_!el0~Kw%!T-~Z<*9`7{Y7OZ85@AxSDX9GJmx}4a;vG3#L zE&V#Jrj0DHX%SX-QbSLK(Dp=>I806-&S1Y`Ta;@zix?!+?8_KS{rT(W2h;=S$pup! z^@v$8@p(tj(|54VcH$!m?iK&syJMMu*gM3uR`;U$90jn2CdwS9T6*(sU1ZbxiFLTt8)QinkW zGR~IS=wLC5tXLOL=O1CCgzP^ge{&o^nD9SXfn9$3&mQgu3kP$LLVd1YC|@U>{i;zZUkVcbFdwJ5RQ%&Rw@! zUjB>%52N9O#GdXN_0)u$6DrfW%pR>`KcK+ol~=-jk$;Jhr!Oh<-*>5Nx@tzfuB{>l zowZLz>+%lps9WeXnf=H9`J28#2+_or+^ zfAyZ1F4gY}a*OL6td}2T9+YElytF0$N@PW-KY

k`i<-k+%3n&GhR+fgv=0_G&lZeW7Z&r@EzAHW)2q#)R#M z7wgoOYr5I^9K4}O5PZuiF}sqLLVJUZAQ`ne`zT3eT~4$OF&7o&br6hd06B<`)GF(d{$?Zidejs)S<9`P^;tgWg zMLFY_$sNgq%sH$zjT&GL_Jp}{1G5Uh zekSxB=kWh=0U{F~(#O?1uVwuOjKJ^_@q@^O9O6+7MVRWKQoN`LKHY{6$sK)P=*|`7 zKX|{Y0s4vz!VbXtiIcS{(JzF8$1Yk7MoDnd%D?8vs`N)R!|PW*#{@*B@OY$EBGgCw zpDit>IOJzq3SiX`*?ZnmZ;LT|)o1NLjQ5)&8e!NXk`DwJj1SJ$zcUH_1jIrJu2fu}3Sy}?0|3X?Tk#(SP1Ryn6gMAGc`IC> zJ|ocJjW@e~Nv@2Q>qq?s7M{g&#c@>l%M{z9z}^sX2n!mrsTc~|H{=Fw@Xq z8UGGDdvT0V*S~wQP)$oqF_$cvLdfm!_x1;ozjNyoTy**_cot<^rc}tB!(PJmcr}zo z!F0!0lP;aWh5`ft0Z00tCe}ARZI%Xe?cPPwXW5sxUQD|2b%EHH7SrH~F7^kC;1h`0 zUEN1igD^0SbBWFx|05PiU-Gtx{WUAkQp;@*%yD(Z7O?7SMoJ8I$Lihz&zbz#0`Pm5 zLuGy*eXk2xkO+=tajahDfp*-+DaAT}@jK@3&7{p{?LB*!Q>4PG-sk%(p|d~h0sY8L>{iFShS@H|G4 z18#KV4xUBc`jH!fiaUkOWg2<~$|Jd)wEME#USuAyI9TV~jIv zlu2(%EI4{-k7aGEDXWrI!_i?Yg8V?2(zJ@M%ajrI`(M~$POm7EnQiR)O*`+Z_+iU5 zkIC3B@MOoTDnhZbaHY>-*AvEma0Lxl+Uh;9pa0TTdFZ^CcZHv z&HQNVxA4O#R(I^rhAr3c9I@`r_w9GTI5+B0-+$}Z({nhHs^>g8JTJ~}u5(4l)i$|= z7tkws7TpKAC3kl+z1h;6=yt9ylQE`J{%{y`R(r1O_^hL{PqzmLWiBkXFc%p z&9yR9wiCv?OOKM_FGK+~PcG~iQ54aoHt19esF zK*#9=)}^|{5a`uZ|G8ynJc+N;dQTm%z?kr52WB3P`Nr(ajntK_$8R*ykps}=O;b1g z?i>ep?jTH(wPzo9{9N4t;5nSV|TzJ9gS3Phe5Q#=_totv(sZRa5a;%Z{wf z-nkbD%T}3|`xVVEF)&ELo>%546HkuKG{eQfp zB3mrkj+^?Ds^)E#Hf|iOe0^)A`7r zkF~T3BJQ5FYg4Qp14@&@}5_ zc@j1Tt*{0+xw&x&+;5nT8TketG$}#q8i{Vty*qf=mn`9Pyn`22tWgbn3%$4bR!HSr z3$-1q#lwcI--ZqKAWdV~$_irZPI6N!EMvD;HXmN~mN4qdd0dL0zFXIq{Xa&A+H&vdTjsI=B>gnQ%eKn}t%VsSi%wP1I5 z4|Kl^gH%e=n}f$}^PS+~GQ(I3GkTE$+ta7#PxZi@Wjcq+f8%akd|mD(Vz19LN#Ni- z91^Z;O_+=82~Hcv4~w87XK{Qs$j@$^P5o#Bcs7bVJmB{s@pWAz;IU<6C+Xj(!MtdK z1eaW1pp34RDwxHWYaNMw-|?5&{|OIT0>qAZJ5YusEv=FeCq|F zJ;wZAS@t0xUmCyQMVvc!`Y)? zh{RW}v0po}Qw~$0^_E(NRVg``_jn@`hd08^YyV9ct;vSQ^T)bbSwXq%kv_RvwCs=_ z6CnWH{}l)~=pZ-F&`turd26)PiAN(GLo2|#bPc--R-%e}%VFd{*tPkKfFAoD;HJgY zW}p$R8u3`Cos|66y$1$4osBF>)*72hZhagVEVR)CK~>rB8=L^5WYQ4QaeuVq3Hw(V| zjn&+8m+eJ^V9$OJV7^95^1kHjf;s!9do2tXG_#aR#2}57Xo+m6p=Ax2uABvaw!5*? z)3)pz{xf`8zn=JRzlf-XD}-=mFmxqQ^&{z?7Y!?EEke z@|l95w(v;^+9zx!RZ5|ay?|9Z!+GD46?x56$Vn(CH`V=s5WP==4iSY}J;zQtj44MT zBL*QBy(rJE3V(lcXhW|$3#YfLP@EP?h%y0jVqZBNirUdS*r_R^>I3gc(8?VNpm~;N z6FX{bZSLNlmb1F7&6ws%K$z&1V>4Rn_UpNj=s;oNZ1o1rIvf1FF%?IjihS+A#24|C zJ>NnO`Y@}v4fH-2qJnSPbG{VM#x+w)$r7dZoFjCPq|P#eg}&PQEGtvducwODEY)q~ zCs2O5uPSMyZ6Al7fcnU|y$o>&S2T^E6&!nvNp8`C6D^Pqf$sP)IUA|H)Mw_N_x`ip|s{ zKIT}FGP38eE9j7e(z-q7d$IRLgFM({JuYU~$>6}hjxA17CQeG7;1s<%i>?G4!h1iY zaKAl21vVw<-a3B^OcDcDbz8#cJXS4!GW22{;m8 z$}Qn*lI|#5-O(bM>`}(cIxRBc!PjY!WD8LQCxr<*ul%gZMJSY92!yv$a)i}E^FVZV z7h7O5X3O*~%<`&MBiT@LEi6Sm1#>AdH%Q8U{@C24DXWSbvt>KzrIb@$=Gb$NtL^p; zy-ouko$_6QCRZR};NwcDChEnCCEG4vT;guz8ci@182l>ufl+lw2^@h-Wl{Om+cj8RJhwo_mC zD17??8PcWqZEVRv7%VqW;Ulx4e`!l;ZyzgUJnZ)Uc-Pgr>+G}wTUV!KL0R^Oe;@`k zzAY0NH5_q}b*~u}AWectYk%;lgIH=i`$z36aR>Y{{OJuSEI4D#h|~-7VLZ^c3kM53 zjrHQ7R7j{UBk^Q#_grApXejlGvaIlYqNb5S38*~Afdr*xfnR2H*eSBX@Zn?muyd*L zhxyEx9BP|71xDZEbF{M9c@*uolr3`Gs;T}(G-*e_>rREGQi!|%a|?A#j|Ki`L7b+w z22mF6xwlW2**}>(M>Ngn$_~r9=ZYr^&v)rY+93xYOV&Xj$asJWaF0cq&8d{--hnvv>1n;AS5hn0bp?9@+PxRI z5DCb#+P#B@tSBmn4_K?!poe95WMEI|=7ylbTAO)9yB6Yq3XQ=8_#spo6beyZ=hV(H zJAvI^mthTT>7E?J>vu!C^7*c@3uDcd1Tni&kKMULf8JHm) zM3W!)?;ikJ+{nu-xA2~>3y%`Pp>{fC|1M1>o9K3XCn3%HSdDGQ&W*;IP|CkR4Rb1J zBtfVCuLBWac)jP*RiT|LKK!o%$5`ULe$A6KZ~xIX0$)j!%7+mvP&lo+;}j6v2ohvo z#ln?;b#61+J{qdN_xG3Ra0Usbry>^)V*|E9=JFlt`B+?w(wBB1JwmdZ^8Qw}z2snu zcUwXjHEP!euZga7D<|Dil1&{{Lqa^JbZ{#jz2-qZBeR{P#q6JQlm0efD>%}tM5Nx$jmGi@hQ<@Pp!yoFsUh9Nxj+FNMmwa31hYSh zJ)>#ldMdDgitZ0YY|OxD$Au|Sx!)Ri+P-_7AEQ2BFh^>(c?G1uFZygaU)O$J6Ip6# zn;KFJW!Xf#JKpHFSlQgs62sAzpmCU`Pn0$yIL%5!D%d9{)Evdf`D;P;Qks~Q9;5A5 z$P_-_?;tl-`CABgE;@6t?@E`sNt&c@gSM8I*7@RO(Bmv#@6sU}X0)_zIap9Lu?DHC zq873S>2IXm7}~FPzW1vyCm&AD_~p=nL^jRL3D@}~-7#p@lC^T}_!X;efOcB|92P-7 zyfnyC=zE&^JLf$JA>9CJF#Of|e8^2Xe*EXjZY}%bT^4UMox%nauO%k2U(aqEQR1V^ zc#PT4U%XNd1A0-#dqR7_bB)ELj%LG#9Y-%6Bc1TskT4ae0cs35Mdxw3``>!56xtN<+S4dRnG6l(#_JD;oPeNVKCbXYI z%75`Z7H)eovVE50YR$ZF-dg8_OO^C_1Qn2^qjq!h@0no2ofO6V4~Jf{uM`47kh~bQ zwTdsG*qbyS!&Ov2%vR7F3-N&{5+?M>rrIF4WS1FxL+fCzz3D#~Wg0PZmHmEtYG6|` zf70l4;FKbYxUj2{#1H4t2Npmj#qHBbFI@s9)ODGp@SN>nnC`|%fQz)^A`%$_rjsI+ zd=C|5y$+#Ini*uv<1pdpU86vw5+>$&w5uB(W@Pu!k6;m$Fj|A>Q4dMn-%d(P%LIO((((%|7EhrAVn=|Crki- zlTVZ8-b`K%Tk?Co+RNtqpn$}lVIFY0rS{wZb$yuuEEa6%KS2Y%%on1?Qf)h`b9s<`cDNk;mn@WIEJE_&B#%N1Cop zepi=gCB;)(%yf<>b}eL&ta9yUds~-6+N|V+DdhJf3Kl+wvjwf$kp9QY8;3N-f#oihFHNDQ^r;a$j#XWM$Hgh`t~e| ziftNNoJpY65s%1lFO{9(uuh4Tzn1%!#Ks@vQVtn6oyQ8M`6QSgQ^s$em8pIwuv|np zdS0<(3h0?uF1Gi-VwdvgeKdGQ7$iM8 z%F1*r2CJi=H~*mPl$gvsw-_S2Us+=a5g*@$K7zcr+Z0Oz=)OVnoWe+r`|N8?k#=4s z@J~d@9TV1Ue}seL6Ich%w7m92n@)kTLt+oVgBli`z@+D#a5CTvP3L@N!hNVfYqv=@ zP|RmUL3J^ZkM_f20$-|p=(#|8)Vd_)61CdeRCCnVr-M)UbUk~<+uaeor#BtLV-oxi zDN7@MZ(`PN9|QJBt8R_M=*U*RiqIG!0m^zo0I*oH(W4$kJ2^3%6cDMX4f%y)ua<*kdy}xEQ`! zPon5L%uN*JUk~;Pb;+HS&s*OW3Lu%cfefw)1&v6hc^>>O==1;R1mz3|M(%4TP~Jvp zbd#!5c!o;Xf9DctnJ>Rf^+2Ec!vapw5Iq!|NB0i)lf39rE~6kBZ#g~j*7Q;=Yl7xi zEm?De`XOt&4!n){PR>9TDH`BcLnCRTSf-lJ-?id|*?7y7sKES&Q=74j_AB_#GUwd# zFZ=`@Zr@7e=)QpenfxXvL5&YBKXgr{OrdTZ&fx5d)Fm_%eEAI{5^<{Mi%qweH)&Bq zo<-u1o@3y`{6@I`zBZ{bK*ptFS?7G29IZ39qu1K!Or=M67ufAR2X=Q}IDub!nt)Dw z_MK-G4|I(jLw44FN?Bz;AZ(N$LQatGp1Z<5?SAqqXWgtgy@8IL_(i%j)Wu}k?DJbM%kER65<@0 z6f-rv<1@EqPT?B5mli#c@V;>DLjD%1zVZVfD5oAplH@5EM6%|#{I>Uvr~^**i@Myf zOGK?2q>5+UY`{W<=l@tM4-^cW=CTdUvAb@m)XzxpelaZ@BwJ=q(vVidEz*1&eY|4t@4Q4y%BGBM0wBGmS=mX ztl3_8Mos=QAeh-#a$q4A_@AUL=Py_foKlxM#?x0yPg~_Z!JA{JP2!5>yr@I$7Fk>g zx(yvq9?mGcxnuR*Escj>lWUrczW=olDFH7R5kqXZQDgV|C)_7mkx*MZWQW-A zj`UjE=%w>a{LSzeOKFy4{6;D*l!g3qgSJ!NpX`(gI?lGsKP*FBbNj^B#K|#8HcF{P zgnFwJ)ZSvuk$LmzADcAUf*nTAOfo9s0%T~cMqo50v^Q#*Zw&IWU-$)c&!ubnz*sjw z1t4JzcH*DTf_&2{uh=hd^DV|geq`SzK*IMvnuZTk;A2s9n3YCx8q?0;C_~Xyj^WX>mz#dm0zysQPllYAgjb&)|iQO>w@9><9#peaeLQ8u$4gy<|=3fvlTSB49< zIkxBp*ffS=9Q!9rM^R<)w1^`5R+D(2o69DuDN2J)X7n+cMn}lkvcKjjCZq&*(TsS9#0YQekg~teknK@iU&*Im- zm9$Zb{E++DqBSeu44RfEoAE#I=58z6S-$klQ;yKr#xxh2cF-)TEb%1KW9AVg1C+H5 z2Pq_ZSt7$Jyf2CpBhm?!_+eKu^^rRurZT?f!zG1GG=N}q7r1K>4Mjn{n8_A zWi$s?Zr88rT^XsuLtwu?xS+1y6y;~bPkG7oJMFX3PoG~e{XMW#2ASEvt$^oCzz5Pr z^vCaX>W`4?pE$Bf`%zKGOnWrkP8)BHHly3=(KI?PuF5`fSe8<_a{;CmR+6D9CM{m@@b^>Je%2Pi2PuL|>)AROL9% zJV_kQ3(HZ#Ez%xs>7Du8k*!*xV**ZKZURI?(pblGmC z(7Un)=@u%OM%FR0DYLORQ)ZZaL^7nk6|zJy7zMNHqN+GAz1LX|drs*0v3%$cMAweiU=qj z(y64hbP0%xN=kQ0No^W7k_JeKAl;yJql7g4=eyB!@BPO8-EWLDJa`VU-*>IK=9=@F z&wS=zF2Iybbd(*)YbgwOenn<)U9*lT)}4Ok@DcKZ$W{V3)&wU>cCh#Z1TlDR&1Knk zohEfti!<>UX)o9Kt?S`GH6$6&)!GXGgTFjCVX57#6Q1HhpNPV?E_%mx$VT3I0 z=%}sZV5dED%O)<{)+v~Cd#Zt7k;?DAj)R4tb?NvdJLSzuR2(})+Y7NGFews`Q?2I( zXQ?2$XipGMubv3AE9DW#Y6l&qhlp0!kiZ+7H`3W_#7@!#rF2x%724IVMZ3tPoOsYH z+y`uac}t#epgxY@cA2h#&w7yVIaLkA0AnOuW}o9dDSk86OvU778WT53X7aN5U107y zFdrx5(48IZB0DZwzB;xgdq-otzbsr)l2E14HT&#_!=XIw{upIsi;yCrIzUKPkgsuN zc&RD_#B}idYbN$IjKHw*7FaZsW7{DY6?zQ zt6v2d*gPDH_AfbaPJ)HslmNy(ohLKZB-ar2efadvv{MV&^VI0NBuDch;Wu(ud9qm( zLvHKU6?~Sw{kUB>;|*AHyuI`I=y7Tg=A7*0Di&jE@D?R>B6kvB2SQhlJ1PE^AdS^83dhp z!374IW}iU5M;Uhh_NXsi z&{~f6$PrRji3tYr*Jp|S=_+bFH@)>n+XNLU+#%LWxJ&n|i74!;HLG@a2=(opg)om1 z@9=9q&+y411+ILMJ}&Z2g_t#iMpYT_1CgR|2d)KN+;>YCaP7i|D;?(yWh^V;;;)RC z&v5`Oh0oJR0MgtM0e{^M0MzN0s8k2Z$*b;vz;X#RF3$PPZYO6SQ!nJb4ZN2;C=jS6 zy>%v$M?oGTJ>zy^j5tzmA5V&Wjgn1So~9q5{u!G>!EzczDq7g{7TTOvFeRBmTFsiDiC zj=f&@wx!^iyECU3+OSmQEehbq)4DU=6W0o6#);F~{7I?zFOj^nroXi(v zC4yUw+tf5PX{@;VcLg4LO82WoJStFi8f)-4q{h?RT9M6QvYk5!Tjqh5*{`6>C36~+ zv2B(CW+{Rmh&V$3IvA(`JGzAwHqfynvaz!(P9V@^1t9_lQ4`GAAYVG(A%wt5J#aVR z9TOiNkMj|m!z5+H%=D=TO!7(TH2dsxGNDBg-nyZ0BhrRhcfPS}HL(i*2HJNar28Ep z^E^jm0|lf!6=Qa3T|6HsvArIGkT1#kC;#xHXOPk9DR_lp_dsZr&U8;uYc;gGrJZWBwgBnjNa#*>@(o+;cgc;y1MfM(kp*PL#c^ z`|>V7N9Dq)zI&Mt=@WR&yy+I4UA3eWam-VEU0}%&$;$vSG#;)gPI+;{4bV@ej^=23~d?R|- zDe1vFwQ!@wlT*@d0pRI!I1C(fN%1aInr99I4qHQ{i@rnYiEy8O(A<(94y#awmb-*_b&DpsHjT+VP)2!oB~ONnX@KS8 zRLdAH=Ts`0nt%u_)%hV5d;k$nda;yZUA%0#nwxF2L%$r)@&N;;q2x8AI}R+;#)#tk7+!Laa8VVN#_Q=j&$bW@ke64*cLS5 zYJHlzGa7Ot#|v*u9!R{O-&%9GfP3RON0W{&3qF$`e4QcW;ye2en?uq;@W*o^8IH&K z&ryzZr_OvRP_k}KzBz`8f``<|lu=5asfoPEdup6mCDk|$$-fhpT{wD6gk*z6`Vdnk zhKFR5!~$P20>Tskx1$Ao79guALUh6)0oRQHT};yZG_=3;e2Jb1 zIg7;=8jb6{gsbZJDZqCYT?5jHJrd@e;cY|e{V=%xo?Zy?uLwC?rH(?4vTAk@8FLbVy+UHmmM6U{;F3T@jr`&iDs1l1a=MPY7RtD+ zBf2r>7cIlwK^*y$!b%LPTlE#!sUaN8#OFOOD1ODs7KwTBalC-X%NT11?5sBC1`$>R z!;@;Y#Y-uk@Y{yrUd%}PA=inHSRI7;dTJnT#ST0O$tKDBE#w31U%j{B`64na9w^48 zies!uHMZIdbmt`)VFS-x#g^@W=oJ9E=@uy{3{`lfroIS&ErPD}ewZF$4icG){-xf4 z4?!(V#B`K_&hG)FmIX^t@n4={K@_@RN)~+&=et~x*l~uGv=T=b!|T9j;>4OuXIDHQ z_MVUz_ieSQPX}@M`+BZi-8FspZ>pZR##u(sQo}JuGG8vpd@W>-x#ebJ3s53AzB}0B zFI{T*Bf&*Vj{@wh#fah(P=Nk!4};I+FFG)orWkmYmDE6_>y_3FXH;}Pgxx|TaJlSR zgT}e7`=QlS(RFP%CeC_5TYo|d0-g@QY>q`B(3iC(3JoE$=!gPD6uS;X4$R@ZlLruM zd9Su52@$XL(J`aIy{j!vpXW+Yj$gitlbk~N}zyTN%HodJz#yFDk%1-6v<`;)6 z2sQ&*dFsFmC@4z+t)O89&%3^riiz`8P%#>=Lqyebv$6`|CTYshRLyBXvOy3_n$f=r zXEk998A>Bay$BO?%MczQWIorfzz7~8M3vBfCTkIb+59$O_LRqDnP0&?#;O>VUMc%z zgz&MqEn##@Y7!jzp&u0(SJj{Juc|*Fqe9)Hl7o$S(3#GG9EwOVw+06_d-vYpVFWKd(rA9=GTqvU-44eQ4J1({+$H{0=Y$_kK1YH@gEs zXEI0RQFk|CsH{1ndAhq0A~P=j zz2(A!Y8j2~$t*}FY<_hR!UYRE#iu-vpq(LdaFrynV!=F+FhII-ohMv@C5w;Tv#GAl0Yl2pS&EX%VZB^!=hR;<89_st(iA| zz<{Yc(9ix*MeWiJlw4UTI~Ei z&Xe$lM(~E5g4$2SYLP@WfNcZGAGQ+3TvvN7cydqn5`v>wqal*yrw(~4Hay8LqInex ze;y%kPdgl$#L>BnBSOv{^pQl5e+zJp%t8D6mw`ZFRm6)A2tX}xX#qKmQ0=RHr4?3y zsHT8h&kL_b2v)n$12t?3bgMT2dw8gW$UznSTQ5f{Ls}Thg)nSGDt`wC1L)Lw?duBO zsasTY2ekLYoT9?SiW?WX`#n zKDwew3j$_m`zXLA^v1!P%m;6D(&cLweUzMpG%cAhn;0TxZyhKj5N*uW>OmD1hHSd| zsRja-#-8xvNsN1udHJNXCWxY(Ci|1f=^pmP;O3*BGS?>l8rmST(=`xwNzWj2bl|2a44nT#h2x6EbA3+@ z{FUNf*vohLRyTMY!+PG^q6s<*R>1^i8e4h?VDX#jDW3sH ze-kk{BUvEy{CO)X4(xGQY7>r2jL7wD&vIqI1$t3xIBJG_(E~v}!O;K8c zB&1Y6;YJ6!3jl)sz@v+C3}!Uevu~z%hSr626rxkY=f3{X1KueQ&_d?dh>+LFqfh5J zv||hgRq8qR%?FB2+!U{-eGvk`Z(QG`<7Qxg9rgvN->d3>sNa}f!hiBami30~&--N7 z+RAU4|HK_kgg8g=rvoFW6aAB+1P8~(%C$YTT&b&z{HVqVw;y&)Zj!Jr#)2^!8V#IDd z7K+9y4MpR<+k1Eh>j%IHc+qCMmWYnV{;${Gj;rC=`A{vn<}(fo^<@Y9yYVWF^A8@X zO+gPr;r{QTcFDRyIM#ae4fiWQC3_zXG(XU>D)OyCx_WcfdxV7b-KI#QS$;hyQg{?v zmct^mk=6Z5UjXT0hd$dT9Xq{Nw~G)qajQ=J>z3+f9A?;tZQbZ|tOLEu^96PxA52v1VK<(SI0BwyPp#Tc zfHx}x;=v%I_P+pHB%M!YT4N`$StLhQ=Id2W8vIEVN|Cw_3NoqQYBz@}aF(piI!Mt{ z_i_XL0HfrrjM`foSLU$jPPS!;TFe=5rAE)IwcIIqcopftSU7VMixt3Bj;Z`j@Iiq-VJnIJb-}Odr+D0amvuLL$3Y+A=S1z}dM1 zRGaXc2!;+;q!9?ILGeMnJOr6!u9fMBrza6dO?F(aQ6rMO!{7txJuCwK5sj3{p&}9G z3It;XdqXmF;*vzQ;7te`=nGEPRrA7qQLM+*q+=pfc9x9+dz{YJZAF7{jK1mKKldhZ zyA|LWr_W{|KZ=uOkNMHnJRbpTG7HpEeBH`GFxyWpv3I>}jj9>DOmlKI?DN|_K9H&B60aCCx zQJWwKlz5r z#C?FAwR)ZGurTiX*eYos&`y=`kXQTVkwdIb=LyD$dASrAM@(-EvrgKqUAt?TC2MUV z1kHYvQinNi_{v!NE%oO~%22l(v4M5ngLH0qGKZ8L&Zt{60GC>#w9WMWqS|f;ui+UtzSQNoOWKXA^_Q1s22{O zl(NQWqVutjM$?(GBU~o;dFC@M+N>J+r7%@@2oh>?dr8-M7{O*;+|1yc@U-}$CGfv` zVWJgs73&UufN-&D&<+{46D+#(uq!CbaSECfi+S3GyUvTOD@C^{IShdQ8H-|QAQ~oN zSN7HI%(LoPqH#s+vlQTt)Gs5U z_Pu=HQokv|l0a4t`0wM~U4cXx3r2Q-@}-#k6#EG06+y?Wpi4ZT5d~~u5tReeP7~sZ zwXO#iz8Ht3Nf2|xG*TY$qo8*)R9@(Mi`7e39k?NaT*J)ZR)4}R>f)n(1shK~Wq1;m zlD7dK^<9=UVa3y8bqLB5u}cA4sJJN;T>-2O)5PBeA!{T(<#Zo5V0y1)rHa6GjL{qdNS;RDN+@GpRf+1q={Zcwa>c#6+wR6d2+#iK>P`Mm{SZ0ki76mbF)z&kd<(v zbEuV$frmT!M2_g6yD23Qw_9R#H9!ZVz9LXD8G?}={uOGU7kuA9gAzW|_2Y`8H1q0j zn!6~lTSL$v^-lih-RiokK6d-yzUPI3)DZcXolyq8unK5hJPFCp7KvVq;ff*@sMunt zndnIxnPqG`P4he7f&Z&(LLXKHL|ApQ=6T4;?67)acDfay9uD5sj~z>K#S8 ze?2>W!Fi4>mvwigu5KYff-}QHPNQ2%1-zw%YDUpeC0CfamkD9 zGk1OVlKfW$%_jf8D)6E6SECGuJEiJjcHAI|hVBChdfN@mvM*um%ka*9&AKU@)+U{z zc=uCR39v?a`>RdZ7dq1vB;3{FM!;-ZudJ$@a~Qjy0}Xy&H`c_wG7vwNz>^4Kzo>Oa zEBBh^0c0j+u#^1^axwRzzFG#YZ_Se5RkS~XX2z)GP$eL5P>4quxkJ!s!|Jq%z*wMn z(7nG0p`n9)q6$M2s3`XMs{`XAF(8ExL^jDpSoM@=-7=b01toe8K_7Vta#OwJo}0KP zVb!Ho%FNWv_)WgYE;Km2QQw&XCdk26?x(JhAoy?Y@wor>9#l&Akme*rE9l3kmqTE* zGc-*u%fkaZn=7`~AfapSas$Dw;P`|{yeGPIH@4~H6EQoSz*-OAuLp)@)V4hdHvv|m zhGro$5?-+sP3%+-Tj^eR0L+li+~1JhFiQ4{_p8R`A~4Lpphn@F88AhR5XM0Lq??&pCJ z`|^z?6;*f1eL4OQ&cOCuJoTvqzX?bS>gT_;d?%hnAE?NcpHF>G2A1#12GI5{;ggqo5cu)IXao|ODLnZRYuGz9Zf_)FZ zP9x6qf?KZX8UGS$B{?kRaI{LZHlYLHY|{r!^r;%J^3+-*!w<`A-Z3Pa9B6fkdm+F@ zw5_To(8uOmzj5LiBX=v0!qp@9e6+Z6K+fz%xM)b19xn_^Y7^bHVze>8O>>lMQQK ziiEmuSpMB`975lBv0;nT;4`|(ULb7*=_X`O2nheZkhs>?^RPr3b>qbS#lL4GMhgg| zeEA2!{`Y&h_DYA19%D95r;jUMo>NjD5>(A=jthHTo&~P>t~`t<`hhwNiI6NLLZoE8 zw?N|tk6b{pI7%Ca2zk2S?9^sf9;u}0_+*nwIBQf{+#gA$4+ zjjb=bA`2JGmm$Q~jWseagWUMftrmW&=o^uO2dv8nSQj-Zjv{kp+73jJWRFGhdZ<>_ z-`wpwkG*;u_UNW=n&tw?H;HSi}?IXBtV-c-qeMexQl z{&^%KS^=sIzWQdRr+sd~!Inw#ti$KRM1hz8i2?y%c1hhQRR8&-lERR+Q#)tefM{-( zY2R4zSI)N$RWbpNt^?wnq(V9YZ;@N(A8vXN+_j&Z7U^=&sVe3sV9p5_=gz*pkCU4; z|G9qQ2R@EvZBFi;ny<#^+*TjT7X(~0?v)$k@5HUVe5ZT#!aj3C$$kwjgW%0@mA0{F z?n~aHuWyaEFzU@?`s;k+@Gp99;>GVbSS)mw1oMtns>|n$>jKr~4jfW}r?PgJAqbP% zZq|84{zH$Wo7f2pn#-RS_d;@MOjt(uh(L>Vo<|XCFc{O3VSwx^EAoyI?4>-;7Nxs7 zBdR-{yp8?paZW60LAy7V?|$Fm%FdYyLwEXJh!s^T$mfjhy_YCQsxA^MbD?L0(PG1x zMNyUCAT~I_y|a$-{oB$lRhJqwch5*|ky!neo}k=ojMMicVjKi*?>vw$D(}rD@Z@Z!r?x4XA<>@l(bANod~d%$96?pyeek1HQ@>1=-gZuO0l}X^l%ouZLZlfJRrODpT}RH# zs=|{+Xz6WDIdqxsCv|C3fK1twxt7j13UEY zsu%R0o*0vbcn$?PL^&p+gT$d6J_w0;XAbh!0(1u&V(tw>a*+xt9jlut)ZEHM=gz?; z7zbGhE5hBt1e6s-I8yl%-&<@X)5Fk^`I{ky8$f;sf`yhJ`j@)`v}vlrbq8ZBkbB)d z_8|SmF#&QcYJ%_DXHV0?#YwxWe&bAlHkHy@thq@PLdrm>20DOEhnI(x`E%VyxL^^2 z;2I_`NsO{=kjNiW<5Oad?z%Y5mB}Q&qG+90tW>qm5S7~b>n+7>fZ{hKG2RkrqBI&- z;RHhx;`zSJQ!GHYur&z@i8`8tIhUKZMfu3>kRE>?T6kCG0<`@;u`Dv(t1f{{Nk)YR=fq%aMMEl71`RhXqRAhkNe<2e~;nEbo9I;^jABb3Fcczr5#8#5@}zU0?@sqk8(VR;h-4$A<1GBCu~^D%hS$t$8?`YoTcvCIf&tZ67+z zu_+vl2;u`dyWHO&4{0ESF{3Ojdg+u$)^rbcgDcVX1vxW(@k9PJm^l5ax@$l{92LxJ zg@Pgj=I$K^zu92@*_+Z&5WzW5mL^`F5GpuX}6 zNL*6^agF~_;GwAgB+9i-D2)R#(T*fVTd(dfpcyJvRkD8muLtQTfX#ydY!JF84f(xJ zoyCNy9e|^ejJ$he_6qu=QV^E+{I@LtsrWV8qwUIyQ12rv?B(wP)ulUJ^7 z#Az?YED*#*hWTsmCPnT5?L4Ul*U@?&17&)6g$AuR(0U6GKm|*YcLIkPX`yg+fd6wJ z0O!&1R0bSkaINZZ{2-%*1_SsmyZB#YjRAj3e7E0I4rCA0+M4H0G`{9<*2y4zkVm|$ zE2?pt7Nd87><$t9P^{AUMa? z4}A(BO3egve^mHp@bkYCJpb$&C6-+ny2Y&bBJST8X`uV=>BZvmOQgvahGaTJem?}r zP#%D!$kqAob_m-4-Q_Ry(l`@P_lna3>{-3D$KTT*ga5rrL)G$h{qCX+w?z{v^{p;dH(^Kl7 zv8y+2&J`t$<+ixuUAp{tDNZurqtCJZTh?gyC7Kfrv;!SbsY1bZ4XPjNK4bu;f!}!| z_8C@zTdKhazv&9>%Fk~|f$(1u`v3P?Xl)yo@a|XRGl^gwY-YpR5Ii1!M7_eiTS$`F zFkc}e+jZ*v)rYcCY(@W>z%7YU+uAi?&@nMp@R5>Ern4GIE2l3%G)5ec0=LA@Veu3y z0D*^wN&8N-FY}xKmZqrV-?Ag-Qv}Tlk-}f$Lc4BZyBvDc&@P*&iJRuTH?-5fRn&Ux z%ARI!gi(Y-PL#wGG2Pk|2>1x>5@P^H9mad%u3f4}LGKfTDTqR0oeASOdLkJxGPbk- z)&7qPE?tN^fChY5GY=)B+ZWj@Ppe7#a+B?%S&ngTYqTsZYVguVgz zX9WWe`9MG#sU6DL$u0t6wg}7o2qNP~KyO_7U>`9g6ZLI`MCv^u9PtK8c|iYQL&Q5X z;jO9iVVAx!)k>SjL(iWb>OKu-V0N7ty^Qb zKxkrtrGfn`-l}?OFGJ0d{0Ksz(maRHB#P`eCT0G=Ke2Y$c6#^D0wwFJy6)KVi!Rv& zKMm0Hy8sc$TH^?8xWJgWP%^omMx-_m-ImfUUlL4X!!eiOF|2LIl(9bl+6cpazW~ zs>q-OdyQ_;Eu@fvcw#{oacJc*KvKHqqYN*hchm6viovjST^KC~^b;+|4Diq=*wNqeMT{qn7S zzuVM1>Q_x;xuOJpDx^j_t0Vo1)mZk~HY|M({sh!i_~*gC9^FuZ!Y4ezb47UC$C=$Y zK2~7pCbD_+6A;Q;!BzcV-z%S|&UDy|S>og64zwl_{ws>(D>Z`)17LS)ea*rfS*qz- zDp2yw^s~TF+z{N83toht?|~y3;?)9?80KN|B@1I*pd_|11Z$ap)#)wf5Sf=KPtN$p zHHmu97WuMTvNckrVr$l@0^axIl(aSC#8i;$LGRTQgR`O4B+*$$t)kd6K4J-JHs)S3 zlKw1_UQr+8-oF0p_R|>=*#cw~Aq))dhiZI5!XseKJr6oM1S!YhH{%_PWuQ_zha9&k z9Iz)7H^k53gP+SrYHX3Qsmbuj%&^-)raM!xA~A;dnw}S-LEW;Gb!udukNT{`qN19; z&eOUft@rnniId)gb3xP(is6d;TIsxG0Rsl46%t{eaj!5Q?ekHSCbzs;3Zks>gPq{t zZ@UoW*`(vkk+2A1KrggvP@owpW+O#CcQhfW^npqSap-%vbrLEjIqj-WwPDGd(M-juDR4)cl*Hu=beG zI`mwX$jo^Z8VqaKK7JQa>C`}?p$Xy_4srIAsDwg0Ld??=KY@7SI8_%mb`BhsY{P2Ei)o zC3Zah>;-s+CqNBVOsGj)8Ys4V!6a}NY?%R`z_9bJHF*9%C6(CMT~&T7i9YWm1%!Y* zDvyg@aI>e8SMy$uuRxtD&2y3$r%;$%4Dw=G#I0fdw{UqWC5Fn2$HR)W+zk2?eSUnshNh|T$^Wc~; z4CA+I{Hw@_7pQo?h1yCL+l+AdE$R?saX%v}eB_wk@%G37IwN%cj732D6`f;)u{kkSb(SXerM-qd5ek3P-S%Fygjob#q>b zy+9rhJMzN=c)YvtczKu4`-ov9LBu1KS=eDEq$?xrZA3Rgw%eAse~gl|?TNEludr35 zb>`3aX%R5eH)e(&mHD$?07EtRBnC32CS;;_vxK0L&$tO6VO^D35Aj{Mlf4m&7S~l( zJ;H(Cz*FFnFh<^@VuWKP@IclL=)T9G(d;OB`j2}7X+e9;JkrG39VbuXD{D;~O>A-M z;oGaYs`Sr# zSH_GWu^9uY1yhK_ua1R^_J6Zlrb}4VFDVhEaa*M_)S!u%wWB^<{^^nopK_dZq`fTf zoZ^G%b1S;-Uoy{;3wiBrSt&|;RP(=nqkcJyEuQ$vz}5J6(U;0-G($ubZ-r>J zN3H>QCh*BTYL2CWNOZ#w)r^0S@eq~=pEWotJA|4byq4ieTc>GRo^w}M-+PZc+CZXN zT}GNwOl?Cull$JA$sEJ4%2$U_HlAvXnQBg6P8&N~yM2+Hwy5Tu-Yd%G;}t5Gc#fVf zr4{FS^}8&5$E~(aArlCq^7sak%l(*-E|~L_c#s1XJ_q8CUH>E6g=9$W?qDfwd3_`t z)YVo8+M8>vxAIhprJ16~rMZ+zvx^B__Ri)I`P%=8oKMi*)ll2@jR|n%zNe{+r>4kf z*)OC%C#Ci=sY*O3*7?uH3tN~?_*0n2b2_pjz1_$zI0o>L9M)Jb%nEtK3QgT?47|1j z*84G@_J88J3zcQ#R5xYCC{R;YW*`)rRKEF+K4f@$Idei`!Izzv*7R()8?NLqD z7d4t9=Q?*3PlNw> zTdI)LSobpJ5DrNUc0Mx19+{Adr~p!E%jAc(Yr5S*Dm`F*A+%s}S3lTY#ui7?ZVI{o z-0Q#X^8Y>KQFDulAGHd?nfhZ>2W>+8WbIU?3wZI!2!Z zi$GLY=U>IM#LeY9D?I9>FaJCa#L6LP8ROJhQ!PxK>He>UP`!$^MpjVh$3xmrp~GM7 zG(UCt#lucY>z&#pDytQHAKs<~xyl6EIgBuR4LjH}Qy)_64I-gb6D{f}brf=f<&WZS zHJ~8&*ZdRpmm!K1HP*aJEXhT9SkI&|&rPKQPeQ{>?#PgdIRvi%S{Ra~_p6b))^%6L zN-o{xC=a@VvbH@xdw=1x#CP#gmOb}0Nw^}t;HSp=`7I27iLX z2FCAX=qOGD7y{*7#+qO85kw{p3fm$-n&mzHkV1Ww9}q(gZ~mxqMv`6IaS5m17qJhX zpuac>OGX?iyNhBb}QL`3w_@6k-ZC_tmJv_JnPZL6?7_uy-ZzFAu-tgGoccv)Pp!R|k=J zl=tC5FK~*UVzK(RYo0tQZiKNSP^W_gB^FPR&MwtQ2w*7G?2_lPZ@XB&-W z;cso{rr%cvKP>STTJu@NNb@qke)nVh5})xR+veavB0pO8pj55R>7-)9uP#E5-4cVP zpXBj_JLeYqKW4C6ujZXxE_`9xSDvVyN5=9tH+j2d*?l8kg1=29%U92FD~gw*UGYrx z5ba^2QCFRTadNw!l|h@Hm8?cyac}(f(g$x#gPyO0gPJhU#6ni92kzV)Qi9V*rOfZezD9WsF@8`e8JPN~=paFsUgGk0{BuSpj_<4yn z;Kw6Gn-P#U0yvD^adIzIiZM1P2sZb{J`$~-r)|APiYh!QyKa_oWuq93Z*EnsT%l&L z*J9$70)vc3ZE{^} zBm<{=WvLJI+qO76ET)06$e;r#<-C}VluR&c> zu432#iK3^uyPl-n)8X@jHYaxPpqKJ&mLAEWlP-7}rrq44=1Pi_7}c&BTnw74>#wnW zY&ns+uR`C)9?w^Z=3EXT*?fF8usZTWPB*4o9nLB#D;6f+NR@l(d4$)o2$1f}GRwX;_lBU;5hY(DZP7QNv^T6QwmUv#pi{%M#YtC!S96c{c;;I1oEuNYTQGWXL*X zwg1pdpgow9FGJgp#dS4vp|9k$!cg0wb-7KM=TFLOdqK8Kt8Z&t=dY4iyX0;pJ}&!F z>BJ+r+3?z{_})r#+zmdmfw?Rp(d)mO%g%~==?K|u2IUHS?vbs@nUi0zig&l!W2A7~ zHTKxd-S(rb@ocuyy3-JL-?@EZY_PDew#>jwC#j=wv^wiq*>Kh^smAFAs!7!2&D7t*)pjxo$q=G1Kj?&qZ&zPT0=?qw)oLhIHqhs8m& zI&NH_*eG_sEZea9k8({29)RT>iohI`n_J07y_s zj@58bQ-g3tD5Z5c)KUqBpNGGv&Xs23dzmNrC0C(h;pr57EI5{8TLAV?JIH%&=_17 zs2ljnZ(0@M^TGbZ8}Guk3ksZ%M0mFEEc|+3%2JinbpP#g*YH8%1JB**=nRJK`Esrj z6+ElgiDl20%D(QHzx3R9;92~wVfxN!K2Pn7>2RrwI$29gFO?IOmz96*YtBl1O!2%rQn9id!4|(G zlIhK?A7njArq*@yj+pPSNRLx^Nm+`{{(*a_$d7y39x9wZuM5(aupjtp@I%Upmv%^y z{N=}21l2MD7LKp1#^9%kx)K6gPcwtV>U60RcIK=H;Oo*KkPnsGiCA{0l=qX&#j>dA;@>{M-3SfkYaM?@8C`TN{&a@T|{@+?mB^_t9>GB>8% zq3c%b)TBHw@1T1XobjTjST(91D$8ulaE29)Ui?OFJ@{U)z`e0{*C|^_o|){>Y5Kg@ z8pW^V6|2eT0_FPqh|7IZ?)6FVclYj1y00V6iF{?22c4a`h652J`Cg5+`%{|-*$GbX zr=877lq*G(tD1h-{HUof;-?&HsdOHuvv!aPb=`So&gVSe9vOVE+$cLGVyK`9YZ&iIU-}CH>mI&K_n8x<)Ok5x0<`!&n;>ioIgu}gk1{Q z)nnum)~&ddN66DLY&@AKV?%Wl(^a;&qRE4f;3!g9)#4`&Z}6Llko4<4l730u8Wo(K z-jtssyhkD_I6v%sLdbRZoK<^NkX|WUqzS9~K-B(0_>HOWOZ=q-Z>^)(WRyLZPS+aM z?Uf5>2U`YPm@_&JUS}56sFb36ME>|ox&+Hj@?7EoBhG&Mxl+X$w&D|~P=1#)$mo+s z>5^;>MoAh0`2^wSVDp)aI=*>-B?VlUt zPoR>+z{+|LGKq2KwhSu#q6osy@W zdy;juqhiTRC^Tvn00Sb^nn!2?g-DOps>SzHd`SEE-#i1ka(q_lflnse+53us)(RMe z23GcAd5Z`87siSQ9aP8*9}dV2O{b#6^(&_;)SW+4#80Xw zE8t}wUU|G%?mWDFrD|t%XHkQZX#0!hzDt=kzfH_N4}XTTeG{UvHqVvSk??x7t(TTX zmBGHk_(eY(!qJZ`{uUc!oHOs{J0-u!^o{Bjco}KjTvN-qZ8}=&lF?*#lU>(FNVnFs zRqbn?aoN7@u+F=<8Q=$#oC<^+U2dkgt-F#wNx^`Vzpfi zP`m53ss1Gu53;9A(7~38V*q?z@5!G(NBHgUiND0GEli?^Fc0tF!#r-NC2@3BJ)W}I z{p4#)uOM>xoqh4??ZXgRwcpe021^wWERA!>`3?H?h3h;OoZJ|ZDjwefjJ9KlY-q6 z={=Zjo^haeIDFRQM_O{iY?)iQyR%y~DsRMe!BiwzJQ1LtBdUHqlE|(uI-C${(>P%S z?PjSmV$8T6o6F=q%N>6TH_(q3h``{hVe_tlS~>%3X9%XW8bZfW8IXX7SXfvP&TA-b zy~|jWJT5t=n(uRn6cU*Kqt0Ac-Ln~TQ*-QgInHZm3d^{v`>{)p8@!3wfzcgS>afdd zslsqDhC4J^RJBh*&)NrbG5q)@8XNq&>S|1qpUXM@WDmD$LBn^QN;5VYntn>pirQ$f zq!&&lMBR^L0 zu=#azS(?*erk#rC+mV|+Fft{q2MKO6)?a>b>nT$Ex>QV(YxTwJFuQvubD_6v(6Xo4 zgjHh*%2ly6Uc9n$r;Ofjp=&@p@ICqCH z3%eG2yce|S&U)w+Jo?wi9fKu`fmSJGnkumy>->0BWvh!p6yhWyszx9ihr(!yGsco&J5$deW~_w6-#hSBr6z{N{)2FXHnJ+UXu< z=joOWYU>s<7{(ly=|*ptgnO6rP{c&t*x!PKt@C<_@0YiqA>rq0`?Vreo@L|kJ@He! z+Y6~AFmrx_=w_RwSJm!@t@ZaVgG`A>O9tB7=$d#&{d>lFsNH?WP&_-hE(f}5oMi+z zXU3v*s>E2D!+#HV+X$P+M_9`pdWFgs#F%Gmn6dBP|4z|caVt?y5qJLvNWzAyAYizU z46;t4uucI;hym;Lv-T>6YKuf{umY+KRCboL-`*hoN0y!GeoiZ+BMKrL-FKyiSKZsq z*wl~Wj{jq!dS@KS25R~9Lap0`vV1q%xi-ElyF7k)xNk4-|H;;7;H?VrTdSz=`?g=p zWs~-3>{|TD`HSL%ts}SUZpx@#WWKC;>7XbmcE=(0;J)^I9?G5iq@?xR;~U`VjTgFe z6TgOZQtWo{pIHjg>1%qBt#VPlPg9MV$Z3?)#mZvypvF4Yzv!NKdH753gssCTH*L&o z&Rd0cKc~rNUX9YY+*4pgsbBUIrDukU(2K>S#n+rB3vzZu*KJWt5JBhIJaqFQcVo4E zn2mvT5H857A-H`q#O?b$B>3(rpuKj>_U{#NmjRy`O=pd00|B^0X|DSCv;X?~HvuG; zD?;$ag*mgI1em&y1VT57%Bkjsl%aQS(1j>XU^9i(Svh#MSMs&D&4t>1z0~}^ofV6r z=@>%Wj^fDjE|SACNNwf1H}Af7E;m?U@H=#=p4QvlnW0}k^#8uzlTu@^|0CRtz4X&5 zxb#&+4cg++uD)e8#`3Cp{(z^PuCz^d@W@tpY~G^SyHuO)7oBM^*4+D5{5*KO;bQY= z=@H?E>)YoNb$7%gXMq3J8phUc3&^MEv$R;m-u*(3cigb z42*F4VuxCME@BV!EN43A_~sK=i1zy{ItG6)PgUt89{SyJr@qL%F!IG2{WY%pOXUh- z!}&@#m9SYy<6TqdK51)0r<1fwB98`ts~7E`(n3crKi?fqu#P_1-Mnig!=GImJ`ho* zzyCSkYdW`{nKN;0)LnQ>y0b#~`0|9UcZt8wsN&VCuTtlhf&!dT-MYEQZ5eSL6*mT( zoyT&N%SN;-95a}w#`hXn<;I7eHn3VBgpvIIl1dWUDaaBRmzqP83uTA^;U%C@*g*qV zBO{n~r)lc3A8 z)&B10q4#3qY1eR*p%(>odJ*CSX?fxU9xL=Wj*$@iw)<3wNk|?)-GXnD#e`==OhSVH z!3XcgF#>`&i=e@1LOg2|epolQWxA4SJ_tjVe{P2guRTucye{A|mZj6TSL^hRz2ETG z$sfGx*VZNm?>@nXe^!H!O`)odzJyA@zlQ~#ar9HQM%wd4*O7p7(_2t!_r!tH_%D?9IFd?TaiF_{Xz4i6H zI!&zNdys9bpvQ`qh`(HJVdTLxjQWalJEAXkO+M%%{zD^p&{{ zq))L8J-o(25Ph#$?t)?+nr{cqveHw@c4a94PLd8!Cds($jDf#xi;gHIqfpo}+>j@Y z*i5!=f&S;DkKW%$>=sC_jLEM3FnlCKNOc_f2L}twy@tZv-2ASh;vESI?9{ZhH(hg2 z@0%<~E8*)Ky&F5J69T{L7%s6CtQp=!w!PxXpkq_)hlv+q?V@1qDj%`mV^++PLc7y* znLWClY|}C@DRy&%jaIcp&MIAg#?1F@0goc9P5RvFHW^}${zvCO%`BlUSO+pM zs|Eiu7Q8B)?0-CYnLAQnRcOFpZnr%nbs<7Nlk18`@P`%Jc(>~>`GZci4*QXKaIorC zN6wy4RJ{F`pD!*mTuwc#!(t_t*wN!l!UNgM>y}#Q$E<~I%St^9%I*{~?NaVYekNj8 z49Zjsc+kuvUqiY&nIs}$MyXC&VaRLSaW_#ViTmcWRduhN(aXf;eegJHggvG&FqZ+da#TJcwD^k!MdHh16%US9ljwMhPW4&3 zkV9Da?Ul1kwgZK1S*uYIrMdj3D0BXIB;i&(g3a&K+#4q5meq9eZU&Uo|JdF>9nt9? zrCeaByvLWyO!KkS8LeSlaLTBUMu(H$H;`JZ$n=8E6Aq`m5=SlPwiYh27Al4P{g{!M zFi)9D_AmIcax&L*I&$3Y_Js5N4r}8Mu4MPrZ`^PaxV=3zp~pHgHQFPR^hw>A=+wx< zr7wcorso{4e@6v4#NZjLcl5?Gi8Wx`b&Wr=8PktewZzh%$megxV|lT_7>m7ex=nZCBsp#1hY zflRZQ!9?GZ^u_flimGMaFOm}t`aQ(iGR5rDcbh*Oz?uy?nH8;A<>)0}HVL@@i$`9W zMzD3xUVm%(*mRzV<>uqpQW;$7vh<~aoaYmJHPLo`*~Dzak15uAlS^1mW;sV$X{?NC zG%9fK+I6`J^SUIP2RB_q(Y$iXQ~OBIVAm3sZ$`r+7x4f1dJCW`+o%gv5U>Cxr9q@q z=?>`*=|;MxyQDz`4u=krmhLW*PLb|Bgdox#_c`eI&;Q?G)sgOPA3q`z-DJzx6d*{mO7JTZiOg%A4*7H2 zpGz4<>Xp@Ou^8_F$wIzmD|)1*&b<4cS(!yintDe3x-QdgbvM~utvb!QbN}T z_Mj&cPr%FVhs}orwI9Tfo?|N`(IkY7**jKJEKws~;ZHq;9K?TSf(iyN*RuL5uHk_l z2nq!@@QqXAoU}iskbA$cgoJy4u!(S7Erpfp_=Z}F%gdy~PYS;`59KfnEtbsI4}3qN z6ljoRZfSaiAjZw;v9L7z`Vt3je_V;HjCSzi&$Uq%eI@bYl2)4!F`>ka_FYWnd({P{ ziVtY#eR`7gnruX9E8&?gLFPSll>KAVg-MbP@i|xO9n|c*)_U@^FEpvB=8h7--4k=V z@LV)$s=W%-op`N&`HA^0l9hNZ8~fJTg*Z`5bnaENn3p|+$4n}|EDMw!Xss>Z@W&jt z=(?i6+|W+QtI`29wwRuw*GtltH8Nc_m*w*T!wF0Y#I$xWOtQvUxG{Wybk3;O4 z1wD&*+7}187dd<587OM=W<`8qk6MY!2@k#_IFr3gYSeJ$!ap6D+KNjx;m$2muV~Wj z%I3w|lg#6CeYJ=AODF51gGK9rPuMXq?>`cYptp#w60e;K}6JRz@ zIS{Sw=<3P@9HsMe>(*f@_x?YU++=VE5bgK*q2j^;mL$3eVm%o+j?ee38a?@(YE8)vB~)r2)0XLni}G*HyaLcyslb z7i{!}PM0Rz$b2`)dZW*-wc@`wo{pCjD6y2kZm-stc3TY1QEscYvAnSd~jOcz~P_NDcqd!WY!pW7CpVHFHLdJRk*3(Z>oWn z(PT0xA`tkQ!-in3whYiw`?ufxJ0wiNf~_FG_~!yXh_z|E%XAbox11q@nLOfP)XqNO zY~nojk2p~K)=;a%2>%ZQF@a0P=aHMw6 zi1czf3E)uQV0CA{tO}*a2osMpdT+JLVy@fF<)k%9iElG`&^;94=JO4KLYFf^5;)hN+|nHt#hP?3KPBs z!9qoq(Z9&XE_bN11{_6H#s_!46YeJ`5)6TaKzI}7%EZBhs2Fwx5lVCm&|U3`*U>E9*8;^fEIp9Ny&!?x()gyFvio5Qy>1`Yu|_Y zfP(u0r8y)JHcZY%|0s|P{I;9Mdv~73*j;9=AVgp>sOLQ+F8@4|Gd=F{q8x4DOWnHo zuq>%9E(kQZ&|*3q2^XhC%qdX5mx9vQNo(nyG_JgUZy;2c&zt+cArD%%N{0CT0ZmWb z)tmmcIK`4s@;IsU?}zHFIQv^+gmhWJSVe7yVN<_@68JX%Ky;=P^&I1jj?Autts6~3 zX`iFo1b(WPMso1Tb5vS*9B#Bk4qpE;H+)$h3~-h`IS<-6fiFngFcJf+ozlVqs}8!v zzXRwl)JEuT1#%LA2s}RdvltbOM)(fI)^(sGKVuYj^E~a)z)BCT_p^6%duJEi>k1(v zP=NdDS0>^`7l6M%Wc^@)aEWMJ9}eg^KW>!I$ZY z%BIoAO;E0YR>aE{bO`lHpvWjLJdTfD;(}4 zQJf%r+7Dl2M+hJ}Gc!a#vHc-Z`XJePJo7w~Cs1PTcmUZ9jIX=lrSH?`V4ww&mV-S7 z=0ghbIR4p#_25C?#DNHPJ9dL`>dQr3n>XD2|F5q=Lse*__PN?Sf7*>YX;!Qb0t;*TF36qe^u%!Q!13SzA%*z2M}9L9UZKi}_w zj%9>~z@F9?|1|o&LKHQjPAeRsHCUCupcv6(9@T&yE)I{#KEm&b^1{I)Y(FlU*_F}?pKxX2Gp5tZZLgK3-JnnX(?|G5&$jC&Z8va(KEyKbQC z-3`p8d;fce9hHFXVH6Ni{X!dO?k;*YU3*VggDDRFBX2_6w!WiWv3yU&pk)#cSP(hT zyZ4x?3FZF#i)e)IlTG^rKZJy#a54*G3?-p$Z71_7;cbVlX-&mGL~&eya?*25PtIR} z<}qeoBrN-A@@rK~Iy7jkuuC&D(?3LS-}kGnjDv7J^)cW_R6uXcQvO2Jp*LtCC6-zT2H&n-TByHH^W{GV?^#LE~VGGO)}Q`iiN zAyPam0OwQlGv8tx`gkeQZVEW}8jnKj*ufk$*nPMYeXz|^4|e^Zi+J;fjFlBj;uDdu zxHt;v&5z8_&wo?Fdb6WV^AwUo4v**Fh?8N%7-`wvb^{R})NYpBWsztmr4tuCls?wt zjju2suv-}Ds+JKyFSPO{{#A1%zr<6g8UyIx#78U{B5CKOdUZK)$+H?*(5Lnrx)UjZM|w zaU|O6FtV38G-}cTJF;ZQ1qjL{BeT)gTJwLLue4w*`1e~S$CGL`tN-Pcj587_f6 z$|HZ>7QoCqbmeRvh0r?4QZZub&(Z8eqbeMrjN_Nt$u5mAj?o2?C&W(LZI{|;Pn5Le zTp$hJd#IqMS~dee3+_t)|7W4;0_6l$Q#3N^Ra$B4?7)_0kheX>4fw@Xhxfk@f?sL* z<6dD0LijQ%_B_OPao-+&KKLQFF)Q{Uv{T0F89uTo_Q*XH8W=V~*@NN#xB#jn{c%mz zcCjSBgPdmZ(&m|+a;KiuIiGoq+cFgf5H+0a4VE;z-$0=rSDl%~g$%kwCyX!_*cJby zm=a*S$XEzM88VfmDbfY9B|HksYw6wlPf$tl2y-R1hu&0p|JKXv-mPBWXPoVdpI90) zG?f0@(~b?d1B7CbkTCVLUk7USbOd8|Sz>WK1lW<)w?({^ z(|)82!{WbGGsXvbs_I7UT?)lMo34%tS3Vp!GsmM-J3Xj$y#LAwT92J+oZ#UEF><$p zxpGf6eoM@e=_vSC8X~d^bJ|^Fq*bM{ULiDBENJSINABrGxjEw@>^>z>e4!V>oBlqP zazJh2mqP;j@l4$?CRGm2sqL82d?`1TlY)t^;=Pi!`wB`RRP8a_}pG93WKYTb7uZ`0!k0tJYwSx&-o{L2Q#G14;0H zD%?W?dlxH2)2H3=DnrVQk)Udn2fN1F?gNwtJ4UiXjyt>vb?MOFbW6G;^Ff!JI*U@* zpyYkiNY1F2$`eL*T+y|tUFQ`nk%eKUrD9PbP5lRy*QveQ)hSjZb+Nc6bnd1BCT0kR zpNLsaylX%Q)O+%FcLKnUsb#KsVM4;Vnv1|g!REs3@6My(Q=0|uIy}(*-*-Ku2}g1! zH3C>P6}Y_{kKJg2?_h?(vxg^7aVfP|!Ejz|cPr4&i+rC>T?+o<@ULeFNFT1*)p|&u zA;2B2P$(wN&cVd#AJdmxP|b_5!Y|(jp9a1t$iGFOt1*5DH{uKPo?mIsKOh_~uq4Pq zaRdY?=a^Q<>sL`2uG;2GW^bMH=i4vODYC}nj^uPV^WMQZ) z$8nw2d{idHRJU2XRNz4(Klc-h$-zqL6QOK9l3A-%a?c@&OMr7Oup@ucWaUlTU=XOQakkEJsqco;i=z3016PiAX9kw?@jr*vC*afZ6k7`pYb3R4k;iki0vi}O}?r(>%sVYYOfSB%KEjb zpW>CdB0y@zWJqH} z;?XIFCj4B&?XT@EtyV!syNIe{Zast1Yf37xqpRf9pwyxtw1{T?oW3`JXA)maK^Sk` z>3{=4py%$*xQcNIYZoVp2t|_awouG0;-3}VfGxG*RyK`a>!tl1R_g)=F$ijnZ6Vh+ z(D!QTr{;ZhTTY=0$aEL~aL^ag`u4+I9)MR~Uy1{$gA#nF%k)VU(H|ZWM^|w_2gfxZ zBxN`S)WdgyqR=<844*PE;4U=dDmsqT3-_aEhw6WkthArteL|@{cGOm?zw7cLMkv2m z+dCxaiw=&}vIG)iOw*^|6RVpf{K};~g0#gG8d|S*1rcN~hKOu%GqM?s{&aiCepT~H z2xul8fV{2tAUN`x@?e;SgmEt9i45inm|}v-1w?V4YIM7{$M%LsT|} z1C87c-odenJNQ%}U{|t^?4P5055OgSE{)DTA!1Vf??~Zn8-J7Cy6hJ|ooM}<|+~glKTkBW^-KCUOT7ewG&qJ%zs{)gm3O6&Mw}K9+S5P-2)VW}AwJ4MtlO9r$ z5RjHY->4XE?GO_mg?Bgg~>JOft|bCfae~_Bj*otWXM@oR_tz z+N%hl48OD+-rVZqgUy~mQf760M!Y=B>F8UL-2_ueCIU9j4~Yoazs?llf9JmiYw5w~ zmP#Xqe+$v`6a>E?$Ic0;1Z_z-;J_OK=6ebFJ%G$xT>n{+c~er?2|VV4lDLs{-vy&v zw>4+=?;MfQk_EH&3Sx<__#$nHw+tFB<=J^1L#(W7Rtzqu;L@d8|8seQz3-lS$(p-N z*nT1UXcER4jv}^A{Gq z9h|85x;NA90KDasba@GX9cBRNR0QMf;OjMUX>m~Az2U=q2tIrG_j*$Q=F@&iSCYWN zV^HaTKigNfr}?`!tr)<-$J@}paa{so_SuD22j`CraIq=+<3mL>liIcdJW{zW75lK` z!&rUdQ=Izz{w%UTQJlZY6Zwt1Fe|ow+w*N*u(` zI{l}^(5E(|M$g*LU$6+c|xm`n#vCJYx8gn8&muwuQa zz%Q1%Xe`S9`U1UOovbHG!^TW8)$gQ*xI$#rY2umQ6|Lxo=zgZ_z@IApZR8+H} z|L~(5a*zs2LP`yA5^yc`7hWcpbo>(xE{t|K zVgAa}N*FZ-78(2KQ59;-FH^_L256{OCM&qPxhnd#bYg3cXDvt0<#kI=Hit{&nn)sm z=X?myeDF~ZCK|r?Zk~>y8_OuErD$AOv$7RoueK7l#iU|#rKCQhRo7%L$yctZ$mqz; zQpdo;3Fg7cbgW+6#^;vggBE>!n*$9Zxn9hVeNOr<1ot4GPv@&Kg<9*FaxdodO<-}& zS5l*ZFTw_qMumWLi$8I=KJpwZd_~UWg|1s(gBhc6?YC3^|A8qb$;g1i#(#Ziw&yV9{js{(=EjHa7qsiqgHgu0Xxpp@<&q&`oZE{aE=p|(Xp3gh~;sy;QhsF zwJ2ZQnFwPR-{FwZ9Dq2~Ucj{99(r2C%eNfDqtapJI)1dchT-;TF8+t6u5R^Rlf&h6iDH17Yg)kOa@uil;K?l>BDpk}*S&U_bsi-X(A zPTk`Fd%D?>{_pL4iO@S$=ki-Cw24xa5dU9{CWQD+4t#Xq>#Wl5{o>n_Pj|s+9NeZ0 zkf!87`JkbUg~9KbM4s_2guz(3;D^3p zit0|+rBfeK%?n5xR71AW_F5L;Cv*FO=wcC@nISLo-CXh9|n zV2P=dJ|9dhKe5=nnJ_gr)=tUXHwj-_eef$&3deNr@!0c)#(o8ZzEX+bxv?LWLCH$^ zb^%>AHTXd9f^Yd2gW`h~uL(9&xv!q-XK5H53 z0<;#Av3r~o%sBb0%Ija6a1`fKKZ4^adUrhC!12t~e>lhSUsU)PPZE-R1|n!a)0-Va z%*nKryW$L@M8>OrZDq)x(S(6_s-sL=Rn6?K(*;DtWi~FQ+935dd>hXDbAdZ*JNlDoIe9+U{H3eOchj;zu zyENk$v7Q$A%2Wp@FY2F9%%w^B2q*xY;s{=r7+`jnp`&m~t9bNan6Q(O-7-F+tMp|u zIn__WTe3XU^`)zESsnR7aqE~@IYfGOL#;Jt4q6-wSHJN{w(vp%9mK9&wQmWfPF?{F z9!f{>>5DFXmea?emhE>O0SMvIDm5BNGm{^KuCCk8RZ{CAUqa>Mq(w8|g-MzOMod=z z*o28DSS1K3xD*!cRJz49o#!s0H5C!vFW_&TDd^vF<#A^X{A#nBfED93f0dablLkrT z%>MGdoam7bIZ+Az{Lj34@86>C{pt=ocX(&|9TXpKXW;4MI`uyp)mkkdzJ_Z7=eKYdf<)fIdzsjsq>XuBRf1JVN(aX*aPx)+aj9KF?R zr&#DUVOj)p98>2TN8Hmw9t8+V7K$uMy^AKFM>^SQFz+XjC+&PX!y119^q-MQ}b_JvilM3ZmJVH0h&~T<7XfJeKsH`&m{sd3ZVFe-K}~ zHU+G`9}*wDgqDo6*miQYTSf`LPDmew-n}DV8wP#h_g@ol{8yvGe29Q}Fhf4pPYlfc zv%1YWa`=a_L77ey@HIO8J_~a6YmapLOFz;w&LxaaGr^8t8?Kf?$=2QovUh`EDES%Z zH=O&w64Ov#y}-G@-ej6CK@t^?V(USM8i!dF+nSwo&vSCS{Ct?`Ew_YoYGygX5h;c# zb+{C*2ra)kKJlL)UwjA|t85P@BsIljelScHeqvokJ~TU3<|sF1HInMx8Mr-LyGPqA zG{YXi5?rV#TB3p0u$Wazzj3zFL_{?8jwC}_4$ang!23-jpAAo zsQxE^*{O&>@9huoU#5i{VgfqHnbjH_$M2dp!Ja?Su)fPQ1wgiCg7(SI;LJBwN z2yFv1eqa9&e!4NjKok!@D}TSV#$DIyr!me$aZw()`DzJpfS$d|^!ptzOAC)z2{oFCtMzdL3?x!`J(LuBSslG-VEt z*po;PCXP(H<5&W6eb>mHH8^YHlyQHk8k=svUhft;v*<_OWFt^v!1w~atYmQA7*ut? zz2T`V6yvVd6}Z`^pkk_s_e^!R)SyL?`E0Z9G;lb{GU9Z_GkOR?w*Fo>AwT=M4*H2B zmLoB}c93b@>O#$$-)HbQi4OZSeA&SPlWAK(kr~kUMgM%|-3L4Sd3v5c{^}^W550Te z)Sg&>G2gff@_IvH;#rzy!uuIriqeqQDI1R)P-A{?=6Jec!JT0|V#()|rdw0~+!K&j z2n*|UF6aeGyYe`!MTM+Yrr#`|m>%lY=PptM)%07Y zjTbuTcYxWQv93TmBcL~qN+*Q>h<^r^0j*u{n`@;{%o-d`j*%pVz6YhCFrxUGx?QoQ zpqh&!=__tiY%!QdDGs2+IUX8W+L6sysBP+4mC-KqvoXJCU3Uvbu4}Y(04Pywr)hTB zcfBbTvcSXk%bc<1xBQsVc+|S%p7;WUJx7OqX_m9Hm?f^dK{EuG6SrhX8)T98_ai}? z1)^VbcNwH2o~%halk2hQpWeh)+zC!&F1+%3-Hd;%_s=*a*K@-u$uYDkWP3NADcNUL zd=ydkMHevLEjns1f3IVQ708yq4>7?v1Js?}V`*-kydKj?J$W{Mbv`;&PkpNmCk24e z*|_Az9GvbG zH75&!!gJ=!?uwVuknIoLUz%R63+b&XUgHKm&lG_)hrJ8{l+ z$+kDa)1@ZdO`e}u9U>Nr`eQ*gmhVdk2YeHvc|n?6bpF-OAPVpG2g(Kq*XpS|q~Hp0 zp%^ZZUq1L(?1t|uJ)&1+=aat~^Rtg|SL^&M8X-bpUq=yA5lY!_^-NpqK5aSP+cyD; z8mqn$*s;o?1d=uMW-)P(7}Ap>9lQCk>O_&Oeri7HUCXgweUZj*2|(=1IF_jTN3s|3!tkTf+L^4We{c12Iu|n>TI=BW-m=Dc%NL&;udexzQOUw~N4adOZE zd1|W*r4V!~HHBWc_T7>+eeg8fQIV#<*)uk(k_mO@IbOVET3t|Z(c;%!F@O)QB+S3&? zHLH^gQaa{BDyaC}J2}p|@xd&6KQZ5#xTk0!tXWvrz5n-q83Npct|f!wsAphUSeUds z6UtpYD|7>(kBD<$6rH=g>g1v#`;R4C3RpZ%&Sz4d*ng5b!z zPb~iR^H@o>N-${z<4fM?UWZnVzg z3+O|lUifD9$i>gMWfvejTHhPg{f+rC>-%(#VR#wi_jt}psqMKbpU8EUzNKJhH%?y^ zXA`S`H-R~}Ns2zxs|*Mk;xNdkR!0q%_tbVaJT7Rpt&QVV!5EzCornAd^>djF^#_%= zi8BxNmv>~E_T~`)Az)(c_=q=6_V(689G!}hCsR@fBsbNiE?RiDRrlh$hnpWLtN+DIYS(sYGDt~=@pd@n(f zMgd-eaBqEi@;AEryPY}d3O_CGzw0-DZ=OQ(>K?4XLb0N#%ciDqF8$AV1d4Gs!gP`! z6A?)9Oivu*^E*dD?ZI!2BH%!RF^49pyq(;yhnzqZCx|?#caEG#R{^C&7haM!_iY@K z?tridOIW_&DiV%q&n7b7;)<+L^9?DYW|6j>f!P{+qh~mm+OF9`yf)=P5cC5c7Ncf2 zIdgDh4eINfY57B!w67r>%1Qv{`W2~ZMXAC+QVhqi{=`wN^*R$A&kGOeS;d11^|95` z7DBUJ9R}$ z$Dk@hr1}!@4p(0cXnD_!jVmuGlR|e4057$BV%3yZA>B%c8)cDyM1yvGQ%Y9bg9xyh z1`4(ScT1$S%VekFb7S&XD1*vsjJ$oKli3IAQ5u`7YM4yo!KSdacc04C&+-uu&poZ2qA$6_8Hx%$RDB*ipF=s1O zdY}3ZqJv+)JuH6%-$+=VjlvpuuMyW~WmRsc%TY)-XdVP5~ z=R;YW&uPB*4kz$g?WCmIK$OWtypd4+d~Yn(Tg@Tup-w~y=donT_U%4;k-+;-%PSBk z`hP>`lBSiQ-O3N6ajOhqJcCjBaV21=dZ1dNSO_|C#;E&Azstf9zU*&> zR4)JQYzj7@yO|i@Sq&}`5;uGsaMsT1_~5%j25>@9Lx^f~(7@aSbwNgE|9W$I_kI+4 zGBD>V%xwSa!~I;GrnyEQl0RD0g`;V8n-2wQdK{d7{g$_-OnNfOV!!E?OwMkyffpT9 ztS(KZ_Ayd4;_O}Mr!t?)U*n&juEw@1Bu%iFd5bmKyUHbOR}Cs2OMfPCD~d33FWm1B zlWa)O`8Zi+`TB}y&b?kx-?-X_x+H6(iZS=tXaBwTk@=c7erw+P?)RvaA$p^F`h6N3 zV_Vuob4}ZWn;M)wwOcKwbE&W0fl9Y@W=8nrwqb21gfCm>qt3SnF&F>37)`yT+FPzq zwYRU#&I(A?u`9&6McA8SYK=?T_0A?OhfDhSJ)Dam;%n+gwc)*?t$JA&4MF<0+ zE*K!zr~S>#v#!Q~VhOF;SZK`U(N+MVT@wa;4pz`(oC5=n z!)R`9?mD-9a^<&gF-S>2=Q-NH$K2!e2a2!sBEcTLt9jMQ{^g0Tz z)yZJEX+g#<5KMPfX{lwkHUmH9xw>N8vn3Fh4EU0LezPJrAHow)f}NN~a2 zSfhpJ0N!R(_7{`*k`*PxsY@;1T79%uTZQ%v=F`NPVvllU0NA+94l4ynnEmdu<7J{# zsPBJ*^@im?E+0pRhR=b>o|QSKmU_)R8W@?7FQ5-;QLVGBO(TKQyY*cH1qFwn3rr>Aqz{b_}#dK0{7f468kHZ6T zaZJ2OhgJE&tYYch*Aka;teEa{EUD)rWf13L{Z8NOSL@;`$u&9B|eByAU z?G~S@o;O4J>ULk;_LRd2CMA0Y3;mh~<-y+XOQ<`IO*;dm=eLuif1D1?@wEMA*BAF3 ztnx7DMi+O!pAtsmw=iTG=HM}SPw-S<@5^kNTPaN_pFNUrwg2US!qd_+Lf1GsHCwP6 zW*cXig0nlkk&>m?nYkOx#&4&or%ZCRzTn0e7EwA+nr{8k!vS)^XfGAKhH6>ReFLgp22IkAGB$=fv8B?9#l5223*8C3i ziF1p@vi5&BXM=J5E1((lFewPu0Evw)2Lmp^=zd(FhU;gH75i+t2xt|msA}P+jTpGr5 zv*}eDH7cn{{TfLzIxY8>(`Zq%a%!^90o8|aM3%OZ+iqSn)Gw#&SAtfixaRO;SxWsc z?5!p#81=m~O!OS+_0SE=C9xo%&N)V@r<@&)D!g_-Fn&vVetRDU^*v7)I0a?qBjjQ{ z1u9=5-(3_0ui1QV&dp%;q&{Z|jM@Z?d6F_R-%DF>!tGklQ3yG0ou+CHzXvD2GDL(+ zxQ`2Dm-p!VUhRkcv;&f;@82?kL84A!hP6{gUVctJ@3 zPG`wOGKcu(hBnBPu#g%hpq!4E zX4U6b)TpX-OQ7+mE~zcxZHs>^mW$M2@G2;8G~xDMP+OR}uq1@i<1UZ5JuflI>^*bN zt$}!34X?R`N1NaeNmCWrV0PEM8Ncn*>NA4yZ|?=M!7T9K2C}5347{tspEX8PW-8zD z^*nc(=MFu}?FzOpR{Cn3EpZ7IuYuw5Gum(MBcT&0FZ7}DpWM}XhvD$dIvY^hrTiYj zJWav(a!Bp3aR>^#CwPxZHV?nS6XR>Xz0u(%UH7LX-`*iexTFf?g*066OE`*zpD#E* zCdMB=w%X+T#Zti2_dqC*m*^!gFCpjL`vAz6RAAO%3MVha%ly6vLrB#4SCO0xZ9t1| z$Eg@}|8;{=aZPsm-Niy?9KusAc8vm)F_G>tL`m zj(w>{`MXzmr~+ophj=K25Wmll_B?AbXkd(j`V9XF)l1J2Z{liE?|JoCZ6^%Ae}+lZ z23*JapFMc@7D!2s`-VgIw-)nc>GL(22nzL%b~(=qTK7s-r+FpRvp@l3bG{1Iwn)E^ zV#CcN$h24>^0god3;XSUZNRBBCQX~uJTb;OFD$giN z6KQn;QQ{m)(NFDaG_fD`Yw#;X_oO8y6&vmxv+s5F_i`}TF9hh1(PxgkE_&xZlmnAF zR8PJJOUkmE4hVsPZS%WZ0PhVCrFspfntp`K9g@yMV&aLjy|O~z@9*#D>(sNXtgJi( z-JZr<1YGaQO7xl^_r5Vrn(lM>!xB#)f6!!18ar7ZuQ?99Q!XHg^wZn`D~8AKQ5DCQ zTk^J#vro_SWTzKZ+g2e3?L*qVR#!rW&;zxyMU|4jv0tp8FRb{7agT1SpWwrM{Rn_o z9FbtIN4*fS`*?e$1cC(#Qb{oFv{Yh$_W(w)dWKf9$K*S@c5bb$SwPAs(yd8Y#aO)2RfTN7@m+j^a=`?%IzAV;J_ z`%PW1&d;}fBnv;w*s{lrV(E5Gst2t3SM)*nP7FZ67Ak8=c;+cA1I**`$R65GMstA< z9vn14x@*ON#u5TXm}1FmmFJy{iY2DJ zj_atRA8XMh-o($W|ICqjRxgPrVL~9*qFm|Af3cYbck9GV-&u^NzKDcC4+1=z^=K=( ze6HN+HMfA0b~jwQ4KrQxT|pTorbhRt-NpV2?3S@_utn5!PElh#_7!ymy@iTXsNB}S$N(wk|l-SgN>xwhlyOca63@n+5O^uJVwX>}&RX_N?|2sTr>e?gPnUwx$@Y6*1>-E; z3u?rZtPW6XO=TbZ(UC$IO1g3M7(=ZbhOEZu<_W^eiLrrEpWQC!V?I_pSTM;YJTUSz z1C~zHafNUyeV(ue&O}GRe1#b;%K_wRO=`sTLJ<|(SPJ7=U(2wFN};&?x+wtsOSxmXPokV|!caErn7BW^#Il|1jj0 zNs>QVEL3L(Qad6s&B;K_x-1I%&U(BcPD%qzA!bF-$(cB{f$_}g zB%}|1Al6%bv1g|LAR%Vm^_f?Y!y|Cczkv1$wfx0SU9jq@8a7-AzKas%Fc!>0+*@e*U(iNc2_A zjp&Ud?mr5{QhZV&%1hgl@C{EDN8YX^dVKTOhRt8o@+#71{dL)BULD~2mJJWSt^`yO zApv+P-TR)`ecsQ^6nS?w8u*6yJVz|hpn%zB4`g1I3KG7lOMtIf4BgT1P|$JRQ=KKG*@hkF-WIl8?RvfXA`Eo!v<5 zMN8FjiX&K+8$SQZc%oy2kWVS0vZu#OC^YH=m5}t1p}a4ngoJVds&t@z$hyBD91k_U zH%n9SurC@uDnRr8I^mSN*D@F1T~z>H1yICPtYng+V(1MuA%u)<)y&$yC2>*B{88~4 zO0zRjoU-)=$bd@WYj-d_QctSgty@L6p04N|s|BKD@a$~s4@!VAMk__E%J*Qja^qgi zJe@yadbjnQxtHK-Ps~ennP+{Dg=)ngppR6(k6dKSu56BE#ZkdKDM6gTFQ6a;>Og7* zDzrJJJ7O$u*TC^eZ%J2s<@|1|In?aaChzbDTCryvq=%Q*ySOJS5zOzv92m7hhRP&O zffve)K%?{=t?2b!K)IIF__pLTBzqwG}k2jGN&k;^rd6l7yEQVP55p>Lg zNMAS)S-M+vDzg64>9K99WqfTxeE6G{DK+^?TG-R^^At74VEqtY`E6V7w!fgja0-dm zzL%qUH9=|<)ZbB^75fV#zf7s5l#OKv`4=6GT76wOUMk%Mk+pz4k~yI_c_1b|>r96X z$)VqBQ0k~ai%C-BTSV;49QZjGWR+yj;*<7utG~H$b-yGouC>3#Y8onEMKp>N1=@2v z);cBT(p!yLtyH+hY3XS%&pZb4-+sO+?lZb*uAZ+@BHZC~CgyCl@ma0XeZv6Sgvz_G zy)8g`_1tnt1irKj7{KTZMgabftM61Y93Mm!CVTxF0}O;h>rhDzKzal5Gf^u}v1`Ex z&|cN*9*6?q^X~gr!FXRL(Gmw7a@DY%98-6X^(3=b4r`LKAa5o0K8pEyJS=!C3T(sg zU~cyV3Ld9TgJU-!u>Rr}H{XypHq4KL98&o={mpyb-&_faw$z`#ghPj|;XO5O`|kpS zl2|JX$rF2IA-#PE+^z{5^&9B{P#NgvXx>xMWEwZ11$o_Hq4TBE9t4>v7)xV{`n7$F zl=r9m;^@IY?q*t!7xZz5KHH#S(rw5#mcYXOG;!R4rLYtuK_Wa|VKOh*xgkYn{%Efn z82~EHsegm2yKdAMJ_vQ!8K9*fG~f%v=^q&|#+U+vPcl`pnYaSu8ZluyL4_3o_4VX6 zIag!l6x%9)Tx)r7AfhA@pMI>2#i5FQsu-l1s8q7Znad=&-D&-BJ2+){;Tc&WR(3(T zk@JkPQuz^~;Tnx-&&6pQ&Q;kKpUYq5s zG|NPJ-kLCDB#N5HPPO_9+BR%a!EQa1y$2l7XRY52-3w=?>iX7Olu8>MC?y!9-+hc}!+*%^cO=*IFLA z)fuH8sP~4~tQ)XoTdy4-S+C*w<-ccS(iyCxf3ejYNNg3?=Ez_0#o4(s+GJW`*KZD) zUDO!siyT^S?u46HrY>$ZU`>>RVD_Ot`_ZjFm19Sf_t_Bnb|N43&)KVPLh^QDP3it> zFkeGC`%ORBxeImUj>XUk|F6b?#O8_A`hG0hA*|pM(3IE5D134k#K22Hnyes*-Ti}l zH>(EpYVIw<;9Xi@qz!=X(izAJ_!nBBB2IDkeHBOPJrY2kUJTaP#jpl)h7KUIo_lo* zGF)<|p);RI6Afu8Fh-KY#24Za!S8vZlFfp_GhUfE8MIdOHi)xS_YWCzg zQwJce#qEo(DVwnNSA+=OUa=-~IDh6}a8LpXFz2K9H4$;%U>uol%!cU90R=-&74j3@ z3?MD`I0eW=&?eQ5MYBe4Jy0jlz1n3bq8`)i99pfE4=4PJsr{xeW_*BAW| z8SpgTEJN$NKM290Ecr0d^wWP8U7J0p7c$AQa+c$?&6$x5AK2oYmRMX4CJU zw-(Z3RM8)svFnSTk=XOz`PXbh`YKx{j_b z8Sodd2MY*%Q&b|OZh6AOB8p@vrGtx0AFvD64KcWLYySW=^yq`=_!l1%8~O8pYs=}_ zQI7n+i29_{HFLh!r3g-`E~{}H4l$Pco#_jqTE+6K|khU6u%id z8Y1NS7sw3v+$w=Yb(_BLHLR-H_ygv-bmVlUSrz~*`t)-GSAdLlR3u^KA3}DEpQ7%z zdrRL!BiT(01YLF#zg~l6CsI6;!0_s9zt53n7lb9H#`};R15DQi_dMGB36)}+eFlG; z4$-rZz7$3~hwo9o$U)v1ObOYZEX@)QK6Y(?L@&TDb0HoYp4B`b}Fev*EW32XRD~@cvW34PZ2;E2U*+t1kBX9h0r45WmT^ z-D^9HN(^u%)zRF<0DPD)uIqF529Jus;DV=uS7qO&#F!w~@>^S58kMGzKgIk00JOpt zeO88wftEhsv_pATztIH^l*3$;o%@ve;NtOnAPc5njj&e9lP8WHpp25jZ-pb>T^H*q zc2LZKk`*AZ$8Pcwf~pSr)~^|w&2G?k?`@J0Z8wbxevb9>_32`%6CsZijh@%OSSk9i zjxelT%m8vLAXSXn8Sz}bkNkoF;H8}9aPUhmhk1Nov^8CT1eGo!{LNuOC-kG%IS#q4 zlv{GA3`>*+J3+!q{Kx-?vhRSWx_$pIj|xvpBpFFKW{4u2Bs$05o6NFH_Dm%q>)4w( z_Q>8uR94E~B$8cbvi{eHp6~Db{KoVD{hn7(FOJjkx$o<~ulc^-SNUR-!&-dVEz050 zk#IEb2mYYP)ELfeTw`HS=PeW9@S^NFN^GPJAf}!4;GI@~FXy z^6RW$96QSZd}~WBc~-@^d9_2S{N?<0qG{2M*gEoRg^cK5ft7iJi3?_zT|%OOXo+jq z&gw7$g7kzP#088bhxO|-p3|p`d5^DhOb+Ru3E^>5-s3_w|GZisz8F>@)Z&aPAVXF6 zfawlj@g~h~HxV*(bS%R*$VAi#r*OuUGbtqIw&R|eG()`5QbW(LW%i+nrrfC6|0nnd zDczNx%Tleo=$4y=E%!@Zig&rRnV6Yxwxaw8aAw8W4M-%klKIo1EF+xPdo_LlC80~v zEfwl5CkYNN7E@xB8}Kk)4HY|c=1l9wyPr~}Pd`saU9u#bZRg9^t$du3=t{J|W9+Vg zehKsY5HbeYmwn)?$i}=)%X@FWROGJ}Ss%V&2or|mHG~JEAwb@TCRoed9p)x-M4bX$ z>;%+Lw{DDX3KSS{PfVKs!PfVYzR{tOt(#F`@X^kXlG^2*)s&2*{B@m=cpgwmQf#Jp zU7C{s*VY%v69Cx^QQFDU#0uJ(e6yj1?=_c*FPSb&2%J2g{AQl|!8KMnR_h8&qhaCZ zOUg0N@6bo8agb-V$3$J){`IXOj76XEB!g{!EIXx@&7{_?WY@3hY%DXkHn`e$_0Sz} zC%85zlrfRmW^2fK>e(3Zc#N)pcJzrcwW1wAPHrU9DgKq+xK*bPYb=I{_Io^p{GD2b z2dMK9@ri?W-yKn^pF$0kyO8R7(hW5&3%1jlAMAgvnU`4h%WvhRwyV)op<8C*z6t5- z7Mpc^d}VkOvR(?I)jf`7rrB3{coeH0txaD*2&2_fgEC|_(2}RaktMmWpv%QMbt@i4 za_F!vGIsYuEhB>GIq*OOw~UYF66ec)mgue8qL`p6_MJ+&Do8HqpJG#@(y*O|{!g)gLWNUv<35~QluC-N-En@vGX39r(UgW z(=6x}X!P|vX`XLYB^nhxjx=zVA{Cc*1s9pfqSYRUk)1N`>TuKBG2)>Sz=^jfw2Q~D zJegv$wtHX5Cfk6>fY?Iuh?63J)aAjBrI^Au^1=)KMKoiz1@hv2axUz2(E@~E7oU?& z_?>n>EO*Qk5Q!G7uf|wVr@|eP2y-DaVFa|#$yk)mWZAUI@Mm~AJ3Xq962~K0?t^-B! zslSrn>nQgroo7O!1|yy=bm9JFycw}0^jTJX^(&iv?6sCA`Co)HE~{TzZvvajZLQ)Q z%_0*&wYOX?QXAh=gBz7UteS~*sTX-e5>ia zv0&dz`BLAAu5CG-N^IXgY{M?MatS-dVQaS}oU0Z7WO4u7;aUslr(@ym$6j zdPg)iR!ls`%350Sp<&E)PCYO2xX8s*tB%nU-HBi?f{=duww=gw69H&fcmufCMft4` z&(bT&3A@yCd)23o8K;4}smRUOWgXM}xG?T?2-ch#o z2(a3c?^HKk0PTY>2HK~=OG@_=qKlsLc;DH-6S|_#GX9~l(CJA-vdNHg8xt@}lcQvY z?)qsgy8@t#{0v&6iDipQt&OJD7~HvA?}9EQG;RT|2uUDJyR@*FYJFHv4Hj*LG-ddV zYT@k*-)54$-gYa9SyO4eb%spC!q-asSu9U|)kRx*wB%J*U+4Ke7@Ez~l|2vhfg|44 z61S`&&C|Dv?3gvOj04W9XDOqanwwb%Yo~-U;VdcP!Qnr8oMA{^#0zcGM4~iEr8Y!! z8;6T-j=2>miz-PJnWG)K+pwWa8*I}?xSdoEcBkE+!h}m>Nig>2?ZLiR zEZ5C*dPVwEW0mEDZ{RgZ+!^+p|0d8Os-hdM{$#rIy7c18r=ti^9917p85+I+LrIyabs*`ENx%*L&>Grg6LRSpO$ z3UCpO3fB!+ezIa<$h4vgFrl*z=neYdfS>lC8;{|v(oFcmZXcElPSFZyu7zO(K7Fd( zJ|@uO$@DqvJ8nsdzeQVZBXKEV@pkeRl8H^5FRZcCd5+Oy`@@a*OGf@UNOC_a$AA2t zgQry|@q*Ei!^Afm5y_W=UL#j8W#2ye{dM&Hdy8Ht-WH=dv^fr%&9yq&UxpDVe3%R_ zu)A*(?wdztM%BkA|V*Uj@<_XG?@ zc!~nY#kWf@`~L8-z|U2EIqlDC>*D3Pa8Sb>L*Tz0++}~2bFLosJkmZ)!iFy?g?%BD zAn5Qod@SsJd;3$957|29`5L4l&lTv+{0A6~B7hji9A?)7*=oy56BtK2?;5(-%cD}+ z04$;?4=_H2PEAFE&t&ATa*P;ePM-GL7(=-(M;mYlDj0V^4 zjGdjw`tc-&p9h%*(LX?+D%-Q(84)NeIWAXqPbvHHail$j@|dYYROihzpBxLiZ?^IX z2B=@3|2QeNsT@IIQ_O67qu|8LfIpmw|9lwZVzsUyFi`pSa@5unH5>jJCur)}69RL< zcln9j7u;AyXnSH@%^GzBtkevCtM}0@%FtsK^!$g1+ zk##hZYpf$~Nc`;M6m`&BMpr@b{f~(W!PEInwuHG_#m8}&2xSwFgQkeHstB4$SfEws z*!uB@qlo!btUx|NbezL$ws7hC{L0gOn@7);LT`Cz-lMy$`-FXlxWfL!Wr?kux3&4M zpYSaky!)}rR`tApR9RFx(xS3kZ8j()neA=-Mo)igmHFgAt$Ofo+`7NJDRpVA`KLwN z3wtt?3-@zNW$a!piW$mMU0X^6#*73v%7D9OU#5;Sid zeFfPU8=$%Hi9!n6Ze=5s;Q4$<3f>;)pxo!Y#H4Z1fOX6pLG}=2H1QtFHsnzZf{f6D z8mXt+q1M7@fDP`;n3NwQ3O+Jd((}?xg`-vN6aQtu%%DrAe_W)x81!BDEPl1~+egdk zgLg-6S^H)T}?%8ue%0_pt(ke+uk#6oYSQ<4IRS_8rM=)`$FybZYYdM?eQyH-gOZ>ryYy zdw+i8yUj=7h6MKqfAC+xxn;0`#_U(@@BDs8xWHQ4MiqJ0B}by>xExGa%B$-$-C%XN z7K*i>q_5n>#V17`)x5$1L;`}G=069hKYtWt`8sv`XVn+KEAMHAiCMiXCK4{c_u_aH zbA`!T-81P)?R>{d7!H14-2iH(;Z9XQ}9K^~nh87x2L1BCWKUr1i+z?Yl2gh(n`{sPaP zPt0anx2H0fHfKXV4tS%cFBu!eE$(Op_lgN|erA~`b!k&FxqCDzu%*a#Zs~3#a0AY) zMB3MRHa`+5(7O8_yP%0hwJBZRxdQIGR)ATsynVcj)i{&LUaakyPN(l1#k@qP`PB#* ze28#H9gvs)8$aCNIire1U7%Gy+kkN7fF0~m7|7q^EC&b-Q;-Nzd4k&k!1%E=BpP;O zIuhdp!%b43p4HKQ;wCM?wHu|u%(*IK##Sp3O78#GLUtbOa?z{1um;uXv4uI;rP7g8 z4fl#Z;NJI{^1%w{k;>uihWk4v31}Iq`K#AXlIIA8uAJztK;jRY|I5Kc1a|lb^0Jp*tc3r&g#jgu zZnk2P8oG~7!|=-aVpYA$BPQvTbdxIbr_NGlIhzO4W6W#NY^F!fd730NV=#RBqPDLK zMZUJH=TGGoFlj~!yMLd)j|%8du|CIl{?SlJY38WJpMy_CPXKcg-E8;`R$j|tL>;17|4R%l$2?YO%%B2n_EViYOPDB_c!)}^|?#;eD*D;IZcWFJBxhbx_in_>NK6p{h zv#zSl&sBumMW#jFcuCt(%$<6??@BRw46km-LP#;yz%R6N$+dSq52pFPlsa?ECM~<( z^BAr(c8_aru8$M3o6ar^y5QPZzA^f6Jd&roc4iJ{Vt&8PV2gSsd4zEJJ~tV@9s1Fx z4X63)Wf;1e4bw{|*@J7yd!6vMVIn6{#B0DNS_7->mU)_nWoxI4E0gj{#3*_f+}HT4>Pknr zYm?X3rP&vKeA~V-X|P3fW$C+?jMV)~Ru1W^lCNZPNNPC2sb$j^nH!rv?hw(Ub5TB@ zO%peaF1BvX-Bu#D3VfSY;69Z-UFK}q+wU|~oanGXZky+^(}!{Mn93IUwTsh{&Z-Zp zA=mc_Ehp8afArL;BAO7dlJT|M^{5h;bH9h@{fK}8#B)O49xx%p2l%q0{w(Fmg<f|;NVEI23)=fMyK`SQ zT76a^-&kjkz$#aBuIJ`bov@h36rZ`NKF~Q{U}0JD031?pfxRS}e^h85oYctFt;~`FtjfN{cLi zmT-|PIji|)U*3;*w&WXYdea-*ojH=+`{7H{z2(-9nDH_0iZ6HCB=dCWwXdwtzj{bD z@GMTl|ITudfqA#Sb}vuiaLT%Mbr7$c{-Qa>*OM^IvG-wu{ewhzeANuoj0cq^D0@89m z^E$RIi$T(dd4#>%pMpDd!nL|1*R6(6nU?hl=H%;X**JFk{8;I0(YRi6{Aj<7U2oc_ z>5bVEwZ`bAa*s{dzLdLW)H}1)L~a)E+4L{C^*Y%N_=ah8RNw4(?b~|vtIVi!@J$p~ zu*~k9o6AidkHA;A&ut1L%RddvN5Oz7-+&mp5E;-jm1!Mts=YHo)czLJg9k&qC+T3x z>L~>U{MqenzlTDTyyu1EtV=fIa&U=52;n$jFU`MYh7rhPeF9AqLwQ+cv`O|1)5Q+fFE?{#7>(BwZBPk}K%Y$g7$XhFnhk@3<- zYJ+6ROr)+$ir?&1VUhOoctXEt(~8r{!j>3znQ$HmnIHg;uy9LDXZUbCItM?sJKy@A z>1QFGrIfa)7~*qRq^fx6nrUgVlia z17jjL8!{QwiS$4%!54>W7Dn#K3<-lKea;2~$W%{6G%N|rDLfxeY4Tsc{8L+VNe|U5 zbo2v%e<=)FAAs_79iS`SA_d&g7VY1%rh?gI%L|Lu8zL%x-mw+QO~8qY=IMcnJ3g=tam!s zc0KH=#we)pifbGwUDjE)Ud>+_gR7_WUu_w@E4W)KW#)VO-W|*9S*`^`45F^<*-!Jz z^yUU_YT1W5>V75JZST}(b5QQCM!fBv>3U{Xp;L&Zv&9Mhhyha*@tVkmef7z(~p;(^&2sRv7l1qG@>!CHZSWH>hxpqAVh2YfrIMO_9pl^XD zZB$yXdHt`lFSO?LO>FJyLG0y}WM6RXIJXNAY}CBx17_J5BbYTxqfe&0btI`6DvTFm z7BIT0LrRVV8Om!$s>sOWWkwi&`AQPLICLmL$^4s@Rmu}adQcHf z1hbR;(tjO;34k6|WARtcEfXG`X%Zbd}G%P z>YjOS{eu|Z@v`<<8$C12JnD-wyxVUgHYOQzOtKuSHJEHs)C@LShGKiRy`q8}*|tK9 zFlhW?7Q=C`83{ebs{bZmMwlZJ;M!MIhAH7L_PxIS@ z7=cQ+6UuTbZzMq=5g**7BX}`naG38p>`zRWxodsh;i*(!BdzbwCcYlQ$C4onqkzMD>0qgfhldp#tr?MTHgBV7 zHg9c}Zo-B#<<;-pAIkj{Yg(qwP+YXXnvhs|*JpRR&G|tNlX7nfMcd-2hB~2E>~<6T zWOx3KYlg6n&2oL++|VBimUrUHGqt*U->GN}&8Moj7@bHMd(AhTZ5MPtYS_(U0B0r`NYr_KJD&>Z+}t=a=vhe)I^ib1 z#2{vH#hpPcdl`QN8Nf^@gy%l`K8V`s_X1aLJt`QDmpa_3LnNu^C63RX6;fz+`Gh`AZR#sjRGa-(D!U&bnO2EbpYl_|)B2>#u2Q z5|N@#Lk`5ocAEE>j*Y7hbUWqV&pTZ{n3d=t##Wuij&rKr(Zs!WShz(jhmCv-SJ;hH z7iF8(`^A%)34Ju@%JxES#746lyY)J6TW;Hpb?d;lHOyh48;O>6|LOYuh?t??Qu1Ja zWs97@!86|tt{*=|a}V0*-rJBa9Za=EHsCJ)Pp>*m&wCvKAvp zhC@d?CS<+0ooM(zSkFwY81z`Hqx<#h#Hq~|vG@}(rR*R46$YNS8igmuyYcHy+#yTT0@vxO!$4@J)$DC+|G5u`8*iWqXZ_1-*Z#3v_=-K z)~(N0?z-MF{XGR31yb;|2k|lKd0=LUMx+%?IYB1a%bK zdP!9m%*>ZWNAxb)qP~M>-h9MOjc<1gexpX3%PD-i5Xz&xDg|2Oo9$mameoMl?!Z}h zqjeF)r}#&2Ep|I=@9d;&!x#G+$s~IX94qRLhSFnf-<`zTo`@5{>ommhG}j29elM>jX`r)hegmui zai5zU*>e(t?=yA;Br$luW4ogSj3nY?leZ5egiBz<*qX9mrL!Q$tYGe+b>u-r_4-QeS(Er21|C@7XOMF4F=h;chNm6RyO3F`yuMv7 zEH%a!N!BKayiF2uzDwphZ2m+N1kR;5#xQsMYRJbv8!-_~Vd15J%dEWAb~!LM$@~P) zE;))`ujjmuT#jY5C4U!V6mh67tno^O^K-@EBgaoH91ML4O(0k5J>()T6bu!ui_u4+16_Htv%+7n3u0$#&ZRTBo-- zH`xSNSF>)dk)F_sdZBudLlhNqw%Gjt7ia4Tej^>o_4uu?2dC&L!Bh~e|G&CFt?}d< z63K`;_K~JQ;#|eCSf|yc&!Gnat~|Wn%c{==L!0SHHi>n*B-lBRr2kseLu{Y`CqFTg)A zeHU2$`yy}APwXctbS7QBD_<8Gx;aB{J6(%^`7n=wMf8W}|NnQuL9Sc*m)1kPJb^<;%@-#OSe#Qz?E4`Z8uQlmC76W)tBI{%8!C=R9k_-|77W-azC zzPTJdODm8$V_>D&`L)tr7;&HINC-i}{V%spic9dtXL9O)${Z93!}RHKLd08VQN{apG)MIK$@7YtGA4Sz4-=#m49!fN3wx^c zaeFpr)*auy*KzP@jlOtru8QEOMG*5Yd5iyqooqDzr%TbS0bB6fyFANwbbN?qZuY#7 z_QgKPQXQV-2gt?#P*rGwe2pdAJoX-6SPOXI4LYlH7Wj56eFqS?et`+$Sqc$KiKIIFL<1-f}`w+rhpUx zxtV%o^}8R81d`G4nNI^c`wmp_75H2{&Qmf0XOUmf8u+*42`~LOLD+8t*Hv&J+J7@Z z|Bca^8!hnW9i^(QrweF)iHSuve)`rwZ2Z6J@3T*!x)j-ESI+<8>|Yi_{Pjtf02SDE zkSCI8%OS~WjD3lCo;BGA3HN`+$8^~%ebAX>-IuFX)~l|g_2f9Q#Z!cH;MH>d{@C8$ zX1z`=bZFSymQnPZ)eefT25{BAVpT~Wxa3P?6bMb|j#Nuej^JDMUbg}>E1x4SkAG;R zXuOSJacy+Yvf&Rfm|S&!s5HmA;`1}}PhQXv-B;`8FRACg)MUnr2@agAgWggj@XUU;+i2g zpjay^Ny=^;adDL! zcy2YH!&f0y34Rbzh2J!C)dZEQ$>C>k!=9@SHPU}!SgWXi8XFu?$CL4$2+fn?^j>( zU4{Aa`ud0nwM8W^Eg4If)sE|<_Cv)V`d|mtP50OfYPu2ukjkuotobcUCNkQj5xQRb za7DzFJZY`91|I7XBCG9JH@?3){Vw5Btu&Ktv?4 z!3%fU7(gNbP=!q1fMtDKXOO(?b<5#DvNqy|AZxaTU$3gZfk`JS==-~al?g1IG(1)V zSKKDNPsH;xv`Aayp^|Seuzvl~!kjda;!8Vc^3o&~ppNp71OUbQg)}U`c0;>*KEHaQ z{c5MZxhyd?pFL?femvmvukb}M=C^THw*waJ?Dg8FEHZii6m5G5#a})AAi$iDGUl6) zXipttr9{6BPZV)l8cFNi>#yH4WlnOpTPOweZHv6X^jV>aM}Ne(_obo9qDYu#??Pio z;k^Aho9acrD4KILfiaMSQ z7>-jES8vco;diy@V0tTeH-;0OKkH1-*8i%-diZP2t+XiLO>l@LQ-;gI5y$`FWtfrs zWVrSvwyoPM*shn3BM+oCXbHtIenh7TF<9K*_V|940=pc#esgh!RHd4c0Il5R0E0A~ z%#{&ndbLK26y`HgP;9=2M2tzo#DHm(p03I6IUTFdq6jgVN@L?O3f()P@7x!Z{e(!J z_qIB{1pPSp>-P8DfWD%FY@5*-{ozb7v;>aeV$fgDyqSB3pC-pQ*z_QRBr|0#N59r} zFwt#k7MsjBYOnH67cVS7YAWq+UiDIyJfp71dT+wDs1Dj*tm3SGcAhP97Vo`r!9R_{ zFITdSx~Z_L0gFw1wd_MQNw~>ZQ>F(>adKkeYdAs6@kvUWNxDz1%#M1lvpAdDhLr80 zGHXjLG3sMSH20hQib*23&ps5oGKykfJK|;}g%d2%zMzV#!WwqmN#8MsY^9WilIAz< z0#MvBDe_x-@q{J&4LJvG>(XA`(e*&Bga=~oGRh(v{gNJV{dVzRc^!B{nTYo=L^|d9 z+b>!IFHx;%WBgB+Df{k`1ft)GQy&SisETY2f-k{UVy__sSM1+1vfipIk&=OK%eDPI z^m31b(oPayCAAuJTNdfJkz-Jr!=@>nl!%&2;3yyITDVP!ZAp$+O? z&zzi}^iUjytvi)+k#_A$E4w35hgC%_RnE}%zm?C!>orrPK{c`TV)9O)t{n4Kt_@$p z{Qy1vR{IaLV*S#tRaOJv3y#rf%BZ$I+MIZaUbgT*pJGZn~}a=1OB4%F+I-DXov4N(Q2+sqT35!#%votn~I=)NC(~L z;_?N6Lu)bGIOsthicGr571OS)9Xa+USZuFC=n2){YPRp(q%Xc?Zx^%W><%k=he2wj z|Bb=UjHk1ny_gpJmLV^*qCTquiZ>!i9)4x~eH4LqCLvez{d~=XEEWq=lu<4nWIuE~ zgg}O^MD(`g+i0`h1LrUd?xuNPgdX`t#CNlJ_MgSoS7h3jYdc=Yjh5kwA}wc3z11 zi5+F6$SO@yxX{h3|2=dk13yppEsy}nSu>WN!aYF+O}9neEtO8t@KYBxlv@c`{#Z6- zks})!u||c<)$`n%&hJS3ApKpIRZoUh=U2)X@Kr8W8~CXiWftSEewDs&V9~}}X#@CG zrWP;uU48TY z!%mU@()E+4>cu?d*ERg(yV|m;F>7HJsePd>X^pa*8khSo**0smdNCMGMt(T@$8Qaa zMCgJNHKz`P5*8Y83L{Fv9>!m7!5l=vcOVhRA^!(H(Gz&5vxE5G++%SEYqDNo(NpZj zS)(VF=p#s7A1_Xn_%>}nrVsW^=qv-W?c4L=B&q7|(0^J2UGO7yJ1a6#kyE}KOx)7_ zx37f^pguR1zw34oZDDa9zj5Ni6eDMgJaj@=)PkZ;?{gB3U{^~3qcmfJN^(t`FVZX6 zX9|rf_x$wN0m}a&XV97FH8mZi9IB{`6a6UKe6ZaH1y&Tz_utj-ZU2P7qly}Y8XmvH6lfv@X51l~#q}!jmb<|s8_{SxEKLNzMX_`TZgmG*6ss6>etdcNE?vW7V4~qk z!cKTg2!1bcLH5%s&#K3q+V7CX>12&j8QDW0WZVaDKSX{f{)(Z5u7nQLJo{Tqq;C7HM(ssLG%u2(crSKzcNFc#oHA{*XW2mXJGs;g z3N$b1@0JH zGK`KP<(6^vVp*{-t?PU6BDyQwO0SOx*#c7?X9Ih$W|e)G!+c*yiz=z}#;B8llR4kK z+G9;1L(CDzaQxaBd8jZCj9IxpiA|i`8_E&d*RyL=8B4Bq3U|A^iHOAv30Uk~%tXz8 zUs0FCmIsOLIU|0R49BoZm|V7SHlLep{K9-ey<@5BunchmF-~DCGP-xMyWnQ&pZ+qv zqp6!g_~&Y!u&DCcG2qSp)bfN%u)r^m0cFYBk^_8C^0ce7ju`Q7OV@qprIw*5>DmUs z@h3|kdC}G21&u&g>@{<&Ql%F-Tm6o!d)v#wIB#@Qcjd}Wyr^d%^v)g!z|TQJX6~RM z^E)4dq_xx#^>>H~dvu6cu!2{7^e(DXTsR1qss24&w#3`p75beS(-IL?`qs7F*4AcB z|H6~wj1+?wCTb`<;eI2bJiZ(B)+9`*=~YXiSuu-B)x3J_ez&cUN4$t=;a~fBGvOLT zgJhQs)6JrmNFAG5PBobu`&@fZlmq*c9UVlEwsht=KE=el{`~AKmnEO|Y={kWB#eO1 ztUX%ur5fLS0*|Tx1(&H%`IEr$5plup{iSr58Wz>j#M)~(b+4KDhe6fQAvo*Ug=Vg7 zVqR2mGY3E<)3*^`eR?3MinYv(ZV54AIx`Dio4l)w^+xpEmTMwubBRGAW_@8|clB$> zLssi5{q44=g|;!87knoKR{g9nn-+b!F_!hLqOM%3*WFhlwW%-_Z6-gpw}4aucdbH} zwD0k%jFhU~0GWdDXVE@2t{a39$|WmR+6w@eJ;} zAL3(2btN5*342$AV}m~+NjK1bQWOKnc<2~@ZFy(9~EmP*WwlDUpW62Hv| ze-uFmLP6-{*hTor?{vfw$Gxo?p%hu86w>}|YV0Z&9YRX7T=6A{4Xu?8p@X}z^aTgi zE>(eAgNRd1tSTd?g};k$I-|nTiaqsj<=(NS{-HiW0WJXr0YGg|Uv7hZ61}vz*qvVA zJ<&HvTJA8BMMB^U>WH5v1_{L=!;gXtKc|A(6Y(;zB1I^Tbx}y?GQHPPJMBj$aVwQl z)!Fv4S?g)FZK!Zz>-0TnpLGfo()gSN0F=OzRhnr-5qcS@(8bQ$h<@nEA3qrXe)HgCtBW7b~FWZ5TWQW02WSZG779#?t68&J4P| zK71Xie3+oh$ck?425O#c#w?Uhbp@^4LSg=B@{$TqWM9F|EH9xU=6QFF;$t;Mtn%Y% ziwR#_ou94j1)4w`I+}r!mP-^K41Zj@^)+r7i;|%Uwyodo1IJccLkBlxPTQim|Es?~ zUKS@Zd!i7rJ8{y>M>}v2Q??noG2v(LauZ`rvwJ6-0}`4tLKjB1OW6V!pECsAZ?U7c zsYtQR%HAq9LmN=-?VdY(3Ct*)5O7>|UGRPBbpeVHkPNxyl{N^1RW!nPw`AD$kej^z z+YLlSoxA}8wdf3?JP;wATgT>(kj4dc`LRn>bzIi0zci?xNpZq&o9+DWau z3DcZ$yq1wNOe#iwK>0o)+Ml6t5xkT;mqk7>yWw>Dfev9Y?UtCkr4-Kn_I>tsZ%}N8 zfb|mlv2YqvP<(hhmAY2s#_3k`zb2ZbEIztdVe49&M&n``QHpPY3 z0ook<`g*u=#vB*dffW4L$6ADwYr8;`ZA)gmJCUrr&psU`WD%?cN!}l7eU#xWbZ0`& z=_xs%cqI+j;v-VMa`n+f-0TBO)r_R}&*!|2Jt(kgT-xP>mCIuIn`-yH;>%eE+E zrLb_$(ohw&NpclV2o*&HDuwL)USI9EPmRj&M zj%93oAF>31Mx95_G<^&P8-jlotxM|9Sb?J|9W<76HgU`Q;4PJ19I_Cfx&9Jc7H)yV zzfP>jOgrwr8fY2F!kt}qQ#o>s!tW+Fk`q#=`pllzpN&4!bY)^6<5;6hC zN4*b{vN?n)fNI|KNB^3RjS4oKqZmUyz}6h~d+xduZczrXG*0%>`0o=$NRzvup?__x%k zQ)~vqsqkqGw$t;nE4lY~movdG8!;r}$ediM}^ zLKGuj*rM~tiBpUoIU%RdT7tzrI8q3{b&?KATt5>3uTYeu2LQIq0ALd(cuH^kBl!G^ zl3*g>9L^%xW_s4MZ3hZP369?x4&h-0XbI=E=hD&L-Ivf%9(pc6w0!RSBW~V<*G=RA zY%%BL@g{d>QVL}3i2p31enjr|_A5u4&~iLrXtHpMuAs)-Vj_X+=Ca&(cVrdEkecG7 zfHz%-&szf>1b*r}N5bC_9r|tn>;)*6gIE1Wn8;oM`P?l2bF?dLTh%h}#bZt#I1UmZ zEpj3$CU0>Tkgi0-z4tmtgFyAsu$g&_*8v{FvOjWu==t8_O6keOgX3p{96u}bK?K3& zjitL{|4lItd|mVy+tkJUl|MdW`E9HYH+ zVhyJB)XWW71Rm;&+lH0UTxKewlx3R)sb`Mo48hr!gXF}7Z^4|T}FIeQ%r>}38$K*1xrvImA>yguW?9)Gj>GRb=i z_}TsUNsx@)7~kLPmxI;E4XW!{o65yrD}+=~=f=3#{=m)f+sKfcO;@C1y7rx`?q_4V zY>bgFjoouzn~@5sO*6L#)_rk{S0j4XVA6wD6sH~yvs4E`4Y(G3wqwHcpHh8=0xGG1 zx+E5f%~&sHq@fZJR*R>f-nKc4)FsCx zh>senp@uxf!`MoWvXoEs%=sgU;P|Vta-PPz~?$ zpt1jW!x1)EAcbAU4>Q?w(QC(WdU`rtkVCiPqbJZz>(sedLU_3<0#MlG}QbJPz3ic zc4sJ*1AE^9c;U9d3s?eCtB#h|`hM$hn=|POW8|#|0Fcyxu)u#AZ{y^le16A#k_Z6B z6bFD+yU9UjJUQ#eDX{{ntn3SCp$lNu$TySLLY1Jl(C>{KS!< zPR0z%hGOq%-K^q2hW&JJ;m7(tw(K;6B3*b9qY~x|R6HEJ6pB)=#YFtcj2Mi~}w%OOTL~XXn`3b_i|~A};+{1C^T5f_E<{zd$&Ol)3z$;yN=dZ)I9C zS|mWVmUFiCw4Vj$5g7yF!-h`~90U_o;IT$y#~~&5rE5H!TCmgN zN!Dq<$4WGalL=jilhuzzkmTThMA}M-Kci(1?K1Js8widuxdPk|a*bL|YjecS$f*0f z$wc6D`qm_h;F-rt!K zOBf-i0YzF%76&xhUm2+nLT`W6We)9<_oeD<4`o^_=dyEj?YaP-k|4}$@}A^6uIY-% z^=J#V?)5z|51evr{EWEux!yL9FBplwxtszU5JYKMdx?!$38$Zd_B)uKbME>(BuYJ! zc9t!P4Og1ulh)M^*n!#e>eov)4=S1KMPcXfSsUe6UK9QGjlpuHqHw!(=xBBs>9=c0 z&Fvj0KU@1{wY{Da^X~YNuf9p!T{2t_xx7fqKnO0u6^(&z=eg;+YS;kO&Ew{|C zeEZ|0qL4h-<73R9C{WaW2aP1ldT$N%wKBJp7@1^4C`L_qCD$r&= zFdud%Czl9Pwu$n6hftdvE;;4_Jo6sfe7@MxX6oRUpuU{ zFb~)7t#dgILQZ_1H2T^a@io*_6cZimg?SK>Q~%n0e`mNP4zlgNQVK7FpD|v`yUC+r zatE*JAzDkciUWxGzXMoO@$1~%NlHuJYUyd^ArFa>?c*S zQ%cyl`@f?#NvrMmflLx|VX`9_r^h{b%6W9Viu01C!Xp40G3H>5c#2!QELL)^v?2U8 z>Jui*(jt)c$7Oz1jXZ@noz(6g6R*AHr`({9mj|S#@~&ZYGpOqcyo661&Iof^xMVs8 z04hd5!rEW%$|5`YiCwy%2w-R>+LkgVNGq!rx_J$h>Ou`HnB#Y0f1BlB@9)YO6hA>{ zG}m$UAy{IH^<|YEChdhaEb(AM~G60a*yIgAQnY{@W0-sJxIS6 zLLfW{2?XynKPgwN_7R|O9}`jKzymVOi{(eqoR}pnL3+x?bTBUQYlx>JFScvXj6zE) zzx)K~tV!h}xOCvYl>>QV)i&eyNm}6n&{5NpmxxOxg(sggDBEbxLlLZPbRH%YrQ|_j zQL8}1t{1RNdUIj;`Le!}3?3>n=JEiF2_p++^h8UAH8Fjj2f`%XQw~pgyoyL$3gP~ux34M+FoSn|V-GV6!S1xlLG>sZi z^&5Y$l2;qT^a;bO!1p-o4qT?Nun&)Kn(JD0W;W%Wx**u3udEy+#*UqD>OY-yHvJ*P zrCdG+mZsUu$H_)5uG$uk27ny6K@L{T(d*!ADv5j*Zd5a6P=ApgU?^Li4XhLbR&=9$(!;OcYqaGfwc>8vqqBg z;CfVdZl!VWYRCUSvc5Z>>i7M>bSjkMSfyp0V}`Oq8HsX^J^(xZ zjDxHq$_Uv}RMI#`Lq>}HuKQ5EKi}V9pGV$4&g|s)w z<}Bq!$+?1#v(+4CUhkuMUGu94yc<07Ex%J1?TqeLgkmoNCNwVcefkUThlIn6=XhQG zHaan)2cYY~5*n%V1-?-A{I&S*{ zLV=PF%j&W>rw7HOm$JN?Dgn%LtrUz_FJv;9L>;5L3g1OH`=QdTUl(|7&ze7X#X(_k8zvI<=nqLq$&1CkH*;9_nk*u0qkKQmSCT zH+9uz{&&?6)kzOJdAr`89(FU^)vaK@zjZLdZTVGGg=fP@XtKQoDpy5VOy+Fn#}uDV zs!(;P>dndF_U7k+37f8 z^0&y^xfkc|#E zhi{S!0BgQ|>X({XzBp&DW`_P(8JJXBURW{Qrg6yqgL-UjjNN{qe>EA{YYYr@SHjHP z_j(mq-E&8>C(?hRdWf%x;+yxmfy+p3Ve$gqEnt1#@G)vN_7*mf>zmQBIZ4ut@^1l5 zV$LLJ7q!dHxfuh>57LiaQI+7N>>_<>l>@8DxdqYbFTCCyG&4By=Cz4xa_1PM>lW&3 z>JwNm8YbbWV_m0ZuYIq}!VR=kNHFfAx%q$JP>ab23>RLVz)h0i=^g_}@jhftBc0G0 z2(j?94)sbI?ed|Kh)LSaUvt zGgJBC^vQS7-j*s9>V5mZ5E!8k214Surdk^$HsydFbU)n%j{4{iwO-#%^Ac|8cH^D} z-??GT>`h0sH6u>zYAnE;j8dB)OCK*jc_Z{ zc6IlsWg@V~!)s_a{5v26c}&dWEjQo+A{0teLIHo%`$DfnU-oW0YYi2j+j02$kv<|t zcS|i3&+$_rJ0)or_+QA0x(mrF^a;TWZFd|7P#361BFEwSo~)Q$yyg81cLy@Aiv$z3j(odr zl8}kZ3di%_!f*Il`Ea=df3g4igA{jQv^~K-5);vXqxAZ?p2Y|RojsAMv-X85bauqo zcCYK}Oj5D+xU;tBov}-}JCq~Pw)1vX3qQ}l7hN2wTI55b7KEhUL))&s^I!Ru3M|#8 z6z>Uv1>3AjLd7nL^Wi?$vab7?d5ddjLLwhxC*xb|vOHit5m<>b7JfOJW{?2&8moQD zyw9_m#H_=JL7y#JK%j_<5eE1&er;^&^ck#7Uby|`1L@A(SM^n^3u$Op)4S}~@XBv| z*48K^j8Ge-tuhaY(wv20{9qs$8lVK(l2~cn=3GaM>|@*!pLHgWkrlUY!*QsZ>-f+PlZ+k>5eZ=Y-ghkY!z4UaZg8#R)J#LTSda^ubWfOKtFyjQYd90J%mcP*?mB8pfIB|Fi=C$GqA9Mz<{Ri2|>HoIipET?p|#z&yHg?4g17ULBv-bgS|k8a^0*+dbe9DeBYK%=RqR{f@KDUJ#CsYE&i`@hl*0xQIOiE=^&u^clgc23-pq^%S_|1!@&DE347+Z(&8CHsm` zD|~*ig>C|u4sPK6}O7suSpyJ_q+F_@R!*$(9Vc(zb2Mm=mY zmhyiV`qLNFpTF|Q3q5pw>o2k_9X-#B^{*dn|Gq{7V+`VjU3q>W*^HV9vcbAH>k14Q zO;A%37^w7LNE`s!@Yqv#uk$g`31LlPV;bmB9;TC!+#_UIa33@wnRSI38I5gijke1P z)85gunVvqw`AyNvg#2oa>vdYwM|+H+RVDsm22$r2$h|$1SA*DoIBZMQk!(yp&u!^O zClHYsYvg81W|av{s|BATy`Qze{6nH*VsF~_yFV|33_w#!y&ropQU#dMzXob9IwM($ zDalA5?&d$LOvN-2+UK$*A~|9RnxfWxXOX5elGmN8+*d>zw?^JJU&a*Jh=E6;cu|pHEq;^9_3>%#SU%^yVB<~Gj6f! z_=Y^lC?p?{&lE)$+>;AR96!4J8}`I~xKgE!zQG(hkvQ@PZ!Um#n&vbd$hCquuE(0D zvZkzd6DV|-ywpx++m$8zu@(KpdoF;VK>p_!VhC@BhD{1Q?(|Nv4VX0%rTG6M2TMMe z{x(R$GW?w^@*gxYXv7_8ASazuOw*_1ADV&yt5GdS{-D3QWWMkFQ`CT&J`I?19n1q{?=q9=O?sz~B9h9fD5tXD-s!-$-=N8$4g#ZzcKxe%BgRLk0# zZox)7jufxb;|j~OdV}+tD`rU8K^`zh>Xet@OF0F>%x!uhs-+n^0@x~m?#B1DMC>T*Sit#2yq>xXvB`^c_Qw16xMaQerJxein1=x_S~ z)Oy79jpt9hW%ThPcb7X9kU0=}Ly9HfjA_dMf?i@s;1$2BobAKAS=E|Pt(`K?70gvP zk|DsmNlT)6R}3M)Q*1sXu=?--7_;4^p$R;Sl0Dh~Z(V$5VAM?6GVt)wC@T}l?Uo@* zS3vAFPLy&iO^rItrLBYkr(%j{nFmF8!5q0?JG^ZSMAEpS>_jJHrNf1OLa?g7U_0PG zJH!u=91iot{edcdv)Ed!+o%j^&{4GvGmHL408O8twfg&TjkMHFQ|2uGnvVBz(^dPeMV>1M zNDA{ucG4WBsbzmGvmIS`LHqjmy*|yxSbPEnvyK#ks zZK6YIFuKb+rQdCZWZ3*Tvp-yGNX3OpTOB-89k49sL7wvxFsX&Gg#@N>?rK%x^$2x8 z{PsGt1G(Q&s3jU^3^%4+8l!s&eS-p%N~Zz%j!A{z0b{8I%a?n;qrhw`04$R*}uhnRlCZ~K;h$%?QdxkYYH==TB&}2HS_+XOD8savBMaB?5>l!`WI^nqa{HC@8 z*J12VoS7OCau_Y3pQH*c6H?C&-sZh{47^sp*XP|Yd2D#9m+hOTzQ-RffYrdS@=Ze; zjb1r7eK$88O4=VF1?)V6|96TdM+r_7$J2C$np{W;*{!1zQb~RB-sC{>27B zU~NZgE?$gPrPpnH0n-ERA!kdRzW;a|IpHw-p%q9k=Aj2+49&9SOR>|^pj4cCxUyV4 z0_a->FlGAAbM$8&y*9jJwSUCC9tbB@ELC9KK73nxj25Z;?8-+SLj2jeQ~s3ORcu%hO{Y0l|fVTDHO=Fa+24AX_$|Lq?216o#K%GcX>(0t*Zlozn&G zp?%n+v{T3qgEsz=hG-`_(LCu~O@-;;@mXi~nW-$f5jd{S2%wbvHB~kMi3^9bC#Y3F zsO04r*AL&8n}3n%z8~6GsObZ0Q5Rq$9R!ga-(%eE;`*O$DPA9T`T$`ydH08>NTbQj ztDfUlXUUyqOF5?7adqPshvm7!i&u?TelHgmIP^cPNA~lD7r%@W2J;s0tcfMd7~*50mR|I#|qQQdu#4EgR$x}%`3D@P<|#G;Ee&SnuOzwMoD7~d$Y zZ(k4hjE1ezX&6Z3Fg;d0A3M~dZjt6ScTEW&ZY5hj3V@Pq1W#0i}x zGU@>B@_w}?zy&sX;A5S#|MB(F-~?ic<3l+v*9kb}m2#jbEy3j_^nHOC>82F%1Wjik zHC#Ohq0DPGx;c@kehi#iRb;G$UKK2jCp&m+$N zt9mw3a|ak95*&F^er3u1qLxct?hc}PWC7l&s5&Cf0`h|52Lm_y8Jd@bn)jECWDU%B z`Ty>nz6&{(tKN^kau7CGu@tM{JoPJzoL^Mk25nyHi<5!u=AVpr=kda9#iGKJCmaUZ z&pbtC6^IUz`*~g4w#!Xk-6C=T@0LZR@qvz!#iY*Is~_Lq={Xs=nN}mhKuuXpE1B{k zZ+eorA@Sh38@VwTWWp;aNFwgkwwt0OT@Te4n8xwM3w9Vs$ z>1zI#rTnPf*Pf#_<^qnl>J-z?qxW-C5IGtA;gT?{`EOpzj0bsQjysJ`Or_nH z1rQ6A_%BbM=8Y$0=xW^PxsP5=+<`eL@~S0x8SuMoJ7E&eQ#u1|_-uEEN~qu+T_4%y zaAK~yAAd5D^nCs1-DjXJW&BDG)StP`=~s^_#bKKg4mp3e#1Vv12P@J~BKC>s!zHX* zAmFl5&~}!0+D0%U4MlNgm4FPj`n4zkeE0xcEr?i}}eh}c}*P>x1AwgFe` zSklbqR6O<~TVvN@;DMO!B9M#wzFgKlWkHOackNbTe{dmp<9iVOo+Cv{KrJw?TXprA zTl6q@o*^_LPEFynu988WA}7iW-JXvSBR}H=8Ss9DjNTW(G}H*T<@jl8!EwrQA;Sx= zX=@6Vo0RVlmqdwNF&RBm9HZdKepk$3)}TH+-V-(5lcS*#{(LXo#y$|qd+3dzKtfE0 z2cC%lO_-BErWKv;i-*p53i+JgHiQ3=g@14xZ}5^&nuhVWbO=*oaBDq6rvpG{eJ$ohxB`=*amlhFbxr*}`oF3$_eBW}TD$kXjM1yn8P^T=cCzK=B)sV*RsvYmm5-%Q|J-5ndQOtRKn6 z)Vf8pT9khh(;JOzGyB7#stJRzo8>OFZ zNV33ni+oG`_S+#i0NVmGlGlP_X&*F?2(`vNOFRTkoyso-IXN!5jz~DECe<6?@AVQY z?8zexYLmTQ^^nh)RVQDP09ubGP6Rqgwa2R1R#S0}G<}$j)U9Uv^ROy!M)2qM$|S}c zN0_oD?(Q2qc}VQ+4LV%%2MliSHH(;n}~y@gW%AzgUdNfLBe!>fD%ISE?X@f zvWR+dSK^-fQ|L{+wG?O-BQEK9NA;ve?a2BD{23X6mOJ8|(vRuz{UA{e;}EwFt5LBC z!)9Hb(Ha}h)=2ztJst@V>C_~5ny*7b5VM2;WzIq^TSE@JQ2zAREk@XLh;_T*gFi(u z*KLe-?p**N^Fc+JUBf9ewfZJWqHOP>elohZ@3yhwo)SpC+WAVN$#`@A0986G(Yje( zQ*2Dp7NTojsPlSCZ<)x0aqMAAW~AL!QIWH1hloxlKvSFh@>)Tv3&=4$-{orEC}Hn- zXTm1+V!o+?Prx` zAzP#{XLMgga6#H)4}t4!N2Gl)-$*^2&QsqrBh}!4xjG_)l_OdgTP;)6N4G!ItLuwX zlW)G1GWYSU$mr>#0lXvZ(GvralU`yn3h}kC^M4JSk1U%<@sx;-GrX;jXgWC{$8@npqbccGWr-Sg!ivb29aJhok~kFXbO zBDT}+*S&FWIupB<1sJkhOFo`>)eB54&tOC&GbyS5Jm_Y%)be7%JB|w1T*_}O} zFB)LTj17==!h&Ugli>_LBJ1_plWs~N$~3m!+<*DPFSs;TO*CS+X4~UV+I~vB+SX`a)+P3$U?pS6g|Wf0hq?P$x|i(j?g|(ZUwDI4$cVq>=Z7nPgYw@YU6ME$ zJC!9Np3HjrQ^Ajfiy$on@p+dL_lEwHqy*A9>UT+d3GFOaPFH()QtjFOtRm$Ap(z$P z_UfbErW>d@54bUzcv8NcThvUV4?G$(eNlY5!8dQ;bsIsgaiS)@UVXR1iyWux(Y`zt zl+H7GZ0-$nR^Bn!Y!v!`_Y|I32#ii+9ypR-dnXR}1#?ySw78M_sgHbNUSfotw(-je zQ_CqoKI&xqJ6)gqc&ZxL=+R@4ecE3Cdv#PRsqmQnVCu*CKHf<2opYe>%kZOlp#Xa{ zppo~$mwc*qZg)}P{mG^YV(b-me)2I=rQK;8NDgis^|D{fw+rj+?xcdYBH%u)di-4C z9`C2>hs>hJg|n9Vttg0ZMruW}6C{&G?i#;A2qGK67nv@Db0XyFPS$%I>uJ|HvFH7D zZUU0j!L^$RDmRlmDSLK91NR{4liY|@|laJ~P_Ciu`Y&8k<886yLWkx#jd*%8pe3p!TAWD@8%rm8yQZSM@{-xx1Xi&_9o)CBmJQxF3rgI#40 z+kM~RAQbOZY^Rp9i0_~n$!>4p3ea%Ri++9f<~}DYYqlrmOX5r0S@Eaw_K_6kSGaqN zI1yK-R7cK^afFqJKXLByINN_3}*fsxm9`o!wkFVrLI(!?w%g|d%*GA|AV zcD=SKzzQazT5svq#spQpgxdEx*ywYLteIP~K-W)LpHDQ?E|@i2pXJ68olN|hAyij! zALXP*`D#5q!U1eEoo!@`30Ht62eq=zVWu%3?HOM#y0bDwOg<7$0I)=w23S59A8s1( zuwRx4k3fV5jN8%m7%!oh=bA4ww#WtKgv3Ixp;j%ED22<(X+F(+>}phIj{19HIvL_F zC=(h~riXm5>K*787%J=kpgqlSSu9%jepF{URE&IPdB#kF{e)bC{Lx8}ntD#Jm+Xtt zBAB7JsPHr*g~FUCiC`fPVp@-VeO5BN4iW_8cw1GGCbq^C&XG7?+Oe9F9na}8=nE1t z#Hkom9TgN6y(n<%Cu2=hiQD_OQyhcO;>GhFWnglcuAW7dG(kjH4BChNQAOF}TmlrJ z&R&?Fjf(Mv?pQ+4ef?hbn*%t4hVT}s?dTUrtw9KVOciPFeq5SwEE-`+?G7~_-7GS16QLed)5~| z9=wcI?R)9o&t;LlMtJ{=90nZ0@*nXE^>2uN`tH$P1P`&`*1s-gaLwdwf1E)~di0{^ z;a_t=T6{A=I!`g%YTUCme$O0Qh~g(7G3e<+ zWHOLKisLsCu9F_!RsDJHw#*aHVcUCQEox1qT6dVkRvnc)abx(oSFo}e5v1Shg_DS_ z#<$6q0qCk1x{96D;W9M4>*G85V4`TS9@S5LyKTevDU8as^Jx%py~cfp+C8_~%XK>h zx~+lE=^?t=q#k2+fKG(C<$J3cHwQesT4{ zHw!X-lnXDH?X$Rp6(F2`2_nFEx)n_)DD>FMa`|9?Y)90O_mNdS(_IgXJfrG6GRHGf zqTPQ?K%YZa3mevF=mNXQWpe(mln-5zGgwSqwD}0EFb~IF%r`R?$b{#Ta2$=vZlr{s zv8H>#W7qVJx*y%~b!Gr0@MobZ=hq_;CBYlfz8!BtdF7R>MmnXTTU~oSXK{8?eOQE7 z?Ja5dK#mR%-`9RViEN@i@Y6QWZWxsQ;_&@qRfC zY^=WK(^PSW6x}2)?uUhg5=%?V|5V-Q2wQQkt5) zuA8B3iGb_+qh3%#eJ+K9Qq(iJNenz7-jz!c?1Bq9BON~>4Rh;BNrGH&S@}I+Xw?y~ z#`)iv$e2CYYBy|ek*F9nyHP4Hp1s_K!-xPux>da^?u#VTSX zV=E$Wqy*lpZ9Cx%F-~`j2HkaR<<-`c)kW|w#1^;>?+a)6Uj{*y<}9;`-05HXLOQQ` zzXQBf3hnU035~lk!NfybD(*e=XiV$Fr~Is|La>xm$Z)0ya4_r!(vNNCbIN1Lo+!9{ z6UM;-i>OWBmC;M6x3}v86~$dc+|lZ5s{;rfl50#A=qgIk{itwk;pr|=sOj7n0Amcs zTU{m~t-a1u$oyEw6qenTiMHNm^W0J>!^F^$lXpboKdOF?80T59+G^1H1X${mnSyx9 zMXq>NQV=N&(Lk^74K{)7r?w8{NG1BIm*BGqvl#CrSBEEYh7+As6b^NEe=5P&L-+(FTOh zF;uw1WtyvQ2k%=Y;Z4yT+4Fu4>B{>rcWzN!)0$QcCkUiq z>Xoj6P3#Od-bH+_H`1iL53~-hHd!!oU4WS^QE8VwY&C2r!CWt!@7KqhC1eE73q4ul z1!Y+ECEbu%OR3}q4}vM`HYks_ja#}i{NFRgA_UiyMd9vA>ad7CYpAQ>;WM)}^=Cb# zIyJe%ZQwo&t;l-I0>m=9r)jiGlT9w$ILe^SM)zuV%(RBmEc2PE#bhWVrk01IBD~|y zk(n03NYxxtCTF)w2I}cMB4`>pdzIMN_1*2m*NMnHseGUBWPl~(7Wm(`ZIPjPx&l^x zIDqhY%W2Bz?n&<_ux~l+V?XsK>f&z`K1aODRKBlHx`4Y%k-Y_7)h8*DRTbd%_EO`} z$aoRcOMRZWG**X?aZ}!O9@v+)X_@v>BH0*;ehrFoUcBx--?lj2TywAYtbEt4WNQmD z212V(QZ#d)fDObRXYxnAn&S$kL!qCe-yHIppNhN0>hLtKY7=>^&)uZLfntu`fY-JX zYf@Rroy*L;XZg5tGHNRG@<4x1epFFY%x&X`^Jw&J&B7(YU@%Xt?*V}O!c06!hW^B< z)fNmr8Y9A`A0SD+hZHYhuFkO0(AjLHdBF3=gm)r1DDtffR1ggj1Ho^19{_TI2yJU;(^~S8)6{k^|5_;KmO%mo^06gQ zRwhYgD&q(eq`;{CS&LD#c-yA!W_P#a-6(sPPhO4fDTPk+r18vjX}d_tBy^Q6K&1TC z;$f_Qrr|9}r=*sRTg{*nb?uRS4eouOV52e&eSlYUtv9fVxKLZshL5-!!{Fmo{v8Fh zJKcF~1+vO|s-hHQ{9)r$m`==L zADNR`23usLu7E{k`aJ-4szW_u{p(}A)7C%m=Bz#sO*b$A@ zByk^t<4Ik>Cbw%yk4Z$BJe`?eP_gCVgRj9aY{Y2j{M}oox+c}>3k^VkHgT+J_i*p~ zFn3?K8atR)cgU`vDzy`?}*<6`gDQjTm!2ZANPUz z&#Y3;hJoF(5#QGZykbnVvKVoJ?4UuC-iAw=$g+fN2}s;Cm;dU z6lBend~5DA{a#s!{7p^DHzN}6EI&!f8a;|GDI2-~y9PgZRw_U9U~4ssFF(}huA6mW zW9l40qVdXH-}0PtF1%e@{GQyzdr(~|!Eeup=dykDTHno~@;a-T+-+(hM9`pEAT=!6 z@7bphICkVXGY^RR1B~Ql)!UIfcy)v#IRpugl%6b2Up=LGT$aOA)O|l`b|E_1^~uiu zij&Vge>;5MBA%sI$RgQfkmReTf^2W0k>alVU^DDv#Sy0G+u7&R$MskFjjKC&8VFte zDO}>K{~BRVyI?`BhiS32*-jCc*hhx|+G-GcA*&Pntj25MYmPWGG(R~4&P=cgGnYM< zg@y+5$QkJ%K0>M-HBMvb6RQ>JX6W%+gnf?PuWz=iZpyI5tXW;rVi*`H=U^76TD-F1 zr(eGSVxNXE>G{#*Sm_&(QJnYwf-$+oHX(19*ps#J(2v${z{qCjs)+~vTwfXZzQf?E zAMP@F(KfIDoXbAoV-{9(x7SjCz$mpowVn+A(vBbNCIjW4I>l#|$w8&~3&{sQ9CA&OK~t>n2UTlF|%SJJ_F`LS7hYtHtrW4obWzFhpc0Jrd38mCsQTOff0f zDyX^E@{F5|6Tzfi z^GyEo&$!{Uc?N()?itwztGUO-e|Zk|UrHqMltvP;kCAnn5ZFmV?CZh@5&B3~S#KjB z%=+LzB3Toew%`A-$EP!P`FVAANJ->{^tt#PWhpwxt<;m&A_~jDH1m-{U4HEx%>4r} zTdVm#RP=u|@axty(N<{UE{BS*52)s1WT{N3;4d4!Cz+GDS;fO}yig)=JMXV4Dns_6 znerX_mp2s8GI3rIIy4tv#T|SNI;t%40hXkgOyRma`OIY4WzJxeSjt?9vs;wPT}iET zUmu$%xUv#@a(tgxaOSq)3@mHN4N@BIC`0W!rX`F{xBhXtf=* zXM^bluPOxwWmtzF>XBg4A*kcuuK1oT>`jpox0!!7Bwi+(I(OuVOXpObNGjPnu5Q7m zuJ|`dnL6Bivbmil%{Es@Xt0$2c&PA+3%Kye2!1He=J;P*@@Z%s^xu{gUVYo`bU*rn z^C+KsrOIw3d)4>5<@K!#SYfJqyEJ!8fs=6jp%_SI4=@~G;QDDuduBIHfFN@Vd!?$q zvDF)W$cmdtSFRTzy0c0*J&*0iySA4X+fRF1WV4f_usY2vrVfujKI_%S8OORa_qJ6AF*w&!*W90iHaCfHT#~O@$L3K=x6sIQ`HmUfB1y*+q#`Rn_ym zHw6eX(jITrn^S(APh*(}usinX8=&ErLq%CrPaMvZNHCPS2Hc06Y)_H=_lja63SSA* z)6{i_s2}bLZ^Ab9>=P93Ig>Gr8a*<_VR`bHt6%u$-jt_0n5W*hOfwiS43AVVPYq9# z-b!PDQ><4tzP>;kgg1@7bjP;W>fn^)rS$nG;1_l6`*M_Wb;IPkTQx6%ULVJ{BpQ`lOR+K$a6c1T-3VR+f-Q{r0hr;Z<$pEpHiV)fB%x za9t>NP&di@&RE&l^G+IlayNXJkQhGl>Q*hs_|2E44nc=Xea5gWMec54(qBs76~#@k z+*U3gF4dpA`5K|LH|c9?W=R zNvA3PxW!Z!6Q4;Fp2TqK;;BDe0Ga?SW~LW6@s)D#Vwri31H)lzT**N$8nTM_2-JW5 zHwRNpMn{Y8NXP0*Wn$=|Kv)+nr29-i#)W3FXTX1yr{y*|2_g&Ia}it&rz?3K|2?HQ z4>9yAFNZG<7AE6@tD42AdQ=72EDxqGF#CYDDwz6+_PF;u8}*<_|}0{co$*s zx5-ISPI=hi{J=9Za*-H%f=O+v*aMaw5^#^|p$A~TJ8Md+)CXqF&R(OtRFU!jJU~Dj zE#`e8`1+F)s>Q;RR*l6Ea;Nc|7S~m!AH*kpNl<2G&2Vi#U;2qSj=|aG@(X8#Xx;j> zOKCV{x0ewssFwrte>4PUxKPfkY?&apORX#?>N_*N?aV#is5MNC$xyTX%_hI%#7sw0 zHL*464}*L`6}^F1M#`ha$9dLU|11UUm(@rQp5ScutEZ!fsECaXi9I#*lwu{)y1$+= zkiRgW>+-u9Qp|DQqiT&AD;LwdxgDF&F@TW%$o6KO$ZHsxzA+TT8trD4Obo;m#G+YL z*zIj|%co;15}Us-SJR7owgzSq-RGi>YZmSMLyhgqo+l^{3rg;yS{SDJLFMW;#N*uW zEc~C>6%=+wYHuVSFP5YaO1(_PU#tEQ*-d?B#j`Y7%0(8hu3DTtRl#uB89V>n`c8i4 zv>V59eeo^y+VAfRU2yO#&nG=yIaw=sA<10yp3}n{s&{tWaB#eRbTkiZvrj{{|4vP+ zgsefMI$410O`tHty{N4*Brb94RTvD$0nvvYTTFsYpLlSruF}74q=d+1bRmzaFP75) zQ~S(7&{!vLQ^y%yElz%W+xxWM-xA%%3pqLn+8^5PSVZ>)>AzRLD7e{O*DFf=$^Lzl zgSYM|-7JWH-~Z?Z#E(oM?zJT!952i)Jo6LTD6GAg)lYm6{m6eYa)369IX*WjNcHG# zb55a~j#-Y;y_=pI-c&3JvRh<&nGjlgBg!E8L9R++iwQYReHY{T8;V&12PWxQ-{z&v z+M~0VHx`NE!o@_y4 z^lisS>AS*s{_t(DD7wS`JGJjWUz{-qF~f&lvRVJWif}ZW>Ve)TXA8B0IN1w!V;?Ko zHZY2}8b=2ikD0c5k$12=!urqzS{59zH&G(d3#e&BRRb^FfBfvnSs#x)&< zdKqex_(XND{3O=KlD}Uz4LO3@wI>ezU1IoD$T@^++`C%-Es+uYR$F6p!-_`WDgK@q zb}L+JlS+cEQ{$M3H$H&NIVgrnJHe1O)mq}zE~W>+Pe51SYBH?s-yZ!s;U*19IA1*(>40U?!0qsA#SHO} zxOaWZQ%j3$32d?g%f=D%3F@?0^c5`cK%AKWki@jg7nz|`9q;d@#nm4X=|=rm zF2D5X)o=vfPbCmn1WT^@0%c~Z{@3R+Ai)mLkNP+to_}$U`7oR8wg6UKH;^D{@6eeflbwpUhnmlaN~>9psLCn@@5iBFz7&K~8PXh&d8u;i92AIB;O3Ed z$T`L5Tc4iRg?H(SoWk%3Jz|kzYxH3F()#g=X73AcSr6p3ZOHt|2I(fDbbmzo4qjHp zw5>FOxFWc2c)5jbcRt?l#Sfw&<=y|bSR3*QU=!K4hREwjD<0HQa~puRrX%RZ=b;06 zsLi;c6HyV7@bM+643P_!!L&_Zv?y5BBPS0eMmz_@iORs$zw77xv^@g@gU+E7ml<<* z!3(WUzjyZUHV@xVb0NBt6et*3$I!;3{IYEvd*=B;&hQHXJu3=<(j3>CRoVY+Mb(Y) z|JGOMxwg9W*RlLDzYp-+IlijuhEkiI-2e!J^QA^*)V$ z8(I<4&;|p%C>|tT128k>3?MRIQOKN(v}A7zz@g490iHqOBQ^1!}AYO;dzQ#7B0lAv{bHDrCmGfFL|bDu|@ zmI1Q;$%PZThTvH}m3uFx6sQ4olWsEh0Vzi0pn^(<-{;Y~!`&5QHNF%hWq7OH zG=#MQIVj(qM(Sql*X<;$NHp~+ybBu)!<@$5G9JpG|!7Z!1^DK3 zF;TFrj`mPh!@iz+!V-*d`%uB-<-((4w!p}Vp5JNh`!_goa-*QjS+|?%1J@a4J;oZl z(%oTH{UQ{o4#r!M(YL2~+`vn1aORSN-p$MuLFiLVFdqDYsB{cqQ^Ghbagb(a*qkNM|qt9H@ zDwZ?Uc;Q~(!n^yrz*ibyQ5byn>Rz;a;S*NgQnR=Pm4gDp4lKeedt-N;oRTxPo9>@} zEX>8=EKz0{P!A)%EXO|aQV$L;;SqENko+u#aK`wd-(_YUA!%t9iZ?h0Ahk5|d5rwg zfA_?8b?$W#;#vMCJpCJu-&o%Pdwf29ySd$(Sa;oNBKgAq{h4Cr9gQ5Z)sH~o`pX~Em9>7^kqxoZh0BQx6m%n?>zLMw0CYF?h3;mz6wE?JyETx#^MZ{tK^ zD2FfLj0CUf8GZ&1vEy{N!j(~Jdp_PpER?QRD0zOAe2Mnbvlu0 zp6&|4cP&N~xG&zy~;m$Fw2Vq13z7oq}PNN+QKwM0c4$OQff&!S1z2&T>{t5 zt&SqNyEQ@c7VGWW6vX7&NXOSCWi~eRzTL4cN}vLyjJ-dCDhvwykJS-CTOVD%^X|ic z52%SAu))S)lzYN3dGw0JmH;*^=TE~e>)mAkME_tuZGJgk?8)!FAXolj)wPa#D{!V` zSP1qFS2t>A8d~PT(3V5N74L6mdxTVi_YF8OYy7zr&j~m!N(75rKf4bz?W)Ry&~y;6 zheBRfSXn)fT{PX0bFOa8$&)&=N8YSWfHy1&h2ar@y*&m$%(k6csZ3MfDEdL}nK zXj5Ecb9?yO)x^Z~^))+0_1C9(1|^%{ayzS(f6ZB&@5D&D0yiC~wUJpF5)=%;SrcM$ zR5KvHN&o|Agd|p=+ycaZ7C=PUI%GV(P4Bw!EnD!{tbl<UK>1iwG1?xsSWHY z6^-5kv6ynE=L@Yc_9DVf#*w-G5@)y~je|PfAzKiwNxQPFt~)0^4Yp+M_>_UFdI&N2 zfe2Z2;mhdAaHX>|2w_`odHJ0jU)*odJn~KX@MJ+*#wViXg&*flNEK+L#e_k5A#zHB zSw*I^!t@x#Ce5u6w_9VZ>ORc;xR%ctv^?oedMz zvWG19+v46lRI_uSePf$+_6a6noJpHSMCDD-YeCy3zrG%$qoZ~LM?0xfD>Rtq&0R-C zl*=NTf>G5RrS~Zs2*fA-Ud<#==i?E$8a-R_v2jg>AeDYW$Ct#I?-6WtyTZVGK!%1! z1FD!3!9RHpq&G^a0&LFQwPZnx-nHaco1(;VcmBFJ4?HJUlksM!zuq`S_%{S937PLKZFe zHy6U7gO^~;Yg#U>@>+K4{$mH=j48j&bBK2_JPx7M$}(f;YD`Br+j*3WXJan#n9LXs z>)v5C7Fx7b>EXRxKD*qo$f$}9DECW&`B=8BJ%jt1X#H*~zG~}vCT>WJ3ssCMnr@5V zIbP^?-gW=lYd#V{%y3*B#`{unZE!}dE}sP)`<6zNa4N4WU}I7?ox5Y%bZoJkVUiV0 zsiNB+#KRSS6yD^{B##^a%&r8v!Ut|HN8fK5lR0v!W2`{@LpfH}eq3?9u)OHhlW0pC zUw_q^sqTyD?OVe(pjq7pinExj-4z2xX7&(F$N?KR8|R)knF#JoMw4Uy#^>or8@7kl zN3!;*CN$Bfxzb~3VE>=m_BW2Kqe+K#3T%uTzE;bUz8)*dL+*X{NKA>dFqb)^QmpjK zPU{R>%tHl6vbc`k2^(}%Ny9hTzqS_@JuowO9nnq(E|fKzq6!2D6OdCSII4eCfE^=Z zmeDB(vTjFU=;OOWoiNSz^x1?yosf$DhyMOOxB(h@$IKgW0PV6#0c%w`MA8X>Bl1LE zOAqd4k?YgiTmQtX;?pinBa`Yo8=yy4J^08^+ZVDq|oDwIp>d}=c+`1Og;S-g$9w~g{o6wzgcxQg@>y68R1vo;y zaQz~-3_v!K@oOr@)?16mxnzoqQIw{Z@15knSrpzB@$jbv)1Sz!z5+nm&)b#@pN^b( z0Af=|P(hS1Rr)40#f#e{{1!fIk0xe9h_-)OA>2+)&ft5-KayV60-|qj84W)%w2?n# zuxZBJb8tP67W?{rI-(jgY%5w>_P4|m#+jdQSOJa<*JVC`!JXg|5`GqK!4%&c+X86m z7?p*U;`F2WX>^od&TN1ebtjpVY}raG&A4E&AuhvF7`!s9yHXsH{kjIf##q|XYXv}q z?>|qH9*ff02HxdJd-UXB#iv-zj^JTC4@cV1opQ4gC~wE|-B_JOGsA7|)Wi?|3I9 zGLbslh=F-@WN@n*f@1DOLQ_bv8#f>#&`;=xrTDXb7(-x5_||xIH|o#BFVN^5e;Kl?eMusCEpzRWy)dDi z&{U=#|`+0cev^QwC#F{|c>9gaJIbs%hYoS(=vjO9qsms8X|2h_iIoDpHtX|rEQHtaY$9@k+6%HN^i`~`% z@|LKd&t@He@K1rZE`S#0h)T~$&!e(Rj(;^wr>DiC17wjMa+~@~ic@sq)d%PG^v`a- zoY_-w{I$|(p37So4r<)83{hmuaO_BtOOyzXH}2nBu@|=E#L;A_e>o_^quy&8$6V*_ z3B-M6P>bbayt*!Rl8e)o_D^OJ&-><~D4i19T}B>fEAK_|OVowsKg!wBT_NF-MbMw^ z27*(2#Et`Jt^ip(RU)`noKqX6ga$NfKaEnRpv9detvsib)RTdPKDzJ4mkY0O9G7HHdidV9=hqd)}QjD;#Z zgE#Fku&>L%|75VP$)$e=r_GuWUw^27A-I@=!kDGoEvejd%T zqP2`ujH%ycbtz$|EJlp*==2sIXJA@II1A$ZL#&#{+_G{uA(GC4vk5 zY5T%qJ29N?T}x=-$f%0JL%bSl@7X|vLTNEs?KPKnlH%~V@IKaSQSt@ew0$=fV|0mw zHxD2nVUGLFLvgEv*n?pBOP)Bt+LRhodV@v@LZv+f=Ccmd!(@af{3)P@$@c8APKK|x z-x5{O7z6F|G|cTIgWS*1RFn_?!zrWSw*=63>Gh1ahz$#dK zdkKYZHx$2by3>LNUJd>X=@U0(a|hR(tq9B*4uDPGfOXP0_=72rAR*j%Tb)_Eybug3 z<9>_!QnF$Tp!Aml`QR=w%OF(mzzC$sOY)fn^(7XuD^ZZp5QnZq7wOMaKw?jOXhyh=uf zj<9*{i_uH(7{C(tL|%qt1aHKlb(k?Ul0D_SQt{t}N^y!dbDGPauAi2AD4! z(yz3KF=$^v`Q;+8u=TSK+iMkiWu-ptiwf~HkqQC@jKjJSfA1Ds%^7I5&U7S5N_ov# zq8l0*l!DRS6{?Xt{N!A4nE%@#h0)|uio<(n_&hi!dK>}sI&)8lRzF#BSRSM$dG(g( z*U@yqJFuYM+Nx-{7V4i;Va|YTjBj}%rT1Qqe(>Z#VHvdfUm#{CU}%u9)aajq;3k+I zaWoSRSqkx_LEtYY~y+&k(OMLntpyx|o$mkgdn=S@UZ>PjYW-9&SX zx**bxV>c8p(|z4rAnI=n*Gk@rH{1PxT%#nYZuAm5JZ3y+$U+_Zb49TZTDgt@a1J2a z_O;F1D@N;l?(xFb`=86bWiz0O;AUJ3UR-@X^yh&d!Vh-Vp;l|_LVN7Y-FPy+J13aT z)WH*kE7XazF1LUP!G?H?F=#_Txk|X=?%>CH8QYC`ANd?;FY9{2748I!`)&kdqhYGH zkZ0|If_W(+4bB``I1hn_xBw{0xxp29*U5m*dy%{Ei;4dHLQt>|fEh{;&f0xQd;){c z-E+%sgMa5v3;yg}CRkHLglSJ5;DUo_8(BHK(g$tfSJzbFwQBpouaIptLm}gGgh;^U z+;5%L4gUcpi=kIyE23mwT1ohrf%7I~v8lY@KwVuH!E>ToKRlCAFhGCToK_jlo8Y+J zw+4&Blj~~1Pv-PYJ+1(mBH8D7iWB;weq^cD#P^MgWVo zM6b1@`NLbaFtBT$)@ytVtTLQY& zI;~@z-uN^e!}N&cWl`kXPjPCav`T(u0C$Ko} z8(xSS$gY|#ui!c3ZC_Qn$_QXLZ`*wydG`R4ogLDPP!51#kQer$BJfK(1qy6JWL%z+ z^#LPLA4f;WTPOX^6Vd|VQQg*CQ#Q%Z7;breBxzef9E6?_O4D=UKbyirg;QxQPHPO1LVV2;=uSoM7^|wI#Z#>`*)qzzVN84>Qsr%gO zU;Zk7Q1K5J0Pt~bcGy=BUX*!k*yoim;w-}vsMrs&-eAu`hCjDLI1Pfji zpSgh&Q%;y$m!+y7RoHNCvk43&(~IWT={4fl$lwm$DsqGlRkD`Q5ODImb>}R z)lsq3D2MF4MSAv+JOZgku2l~Rtw`o-U5`_vPfsCr zu2R+CCFO8`?a1p2IR0-)h9c1OK{p4+4h`1ijk8@HLx%neE)^c-^KM8v{58aBXf5IL z85h1RGT8;Q4$I`pVXM>7(QhgvgEwrL{_0_6!hRLNf<=gJD7$C{ngr65#I5tmH$nN9 z(aPt4K;`j-CfY$ZgQIDqD6f;-Q2s}F4YVHg_bz5YZeHp_0R%xCuEO!cf^2b%;I+;H z>=ZlLDS2#06RUIWh_o0ucE;p3K&DKn9?Xf{I^7j9B4&1FHeD6S%);_N5Srl87AOG~ z!{CKCUvm4jnw?W$IBMg(0#;*4??k33{0bgZJ5>(hfT($AM8@yPxhG-3!kV(ax$V!b z8LkX_l8_|%6JZLRm;dMZgID*TtEc+tF94(~4U5eklMi340IJl3922;bb9aeufXML- zaDk0~kK8IQAlV!x^)3B{(${XU*`F{sz0jsBC4FG)X87c9a4~fq0Q3FgL*B7|G(YQ~ z13zWFbyiD~2f~?{GOXXR$PR6kDmR5ImaqiFya|t7>|xKT9goc`Yt`CgMJplRk1M~N zfGNz({m7JRW>e03xYzM$e`{_@{?{`7hP*{DX|efJb(-^13a*AzRM+lZ_7cuqA6KXd)TYTjJ0lq(*@P&SV`M8M^VmCEXdqiw zBBP9~P)4$!>!Z8-{yx9w_5An!x`p#u*LA(G_w|0~Lja(*=A1hixpjG`PebLM@@E1I z-L!w0TVF>;rH7j41}-c(pxkO@gI|oaJ9HPtij{m!$+lQ&`Y^?vk@d4(7)ZjqHg!XzO^ac2Gu&MFl_+B{73}HB z=jM<8r?y583Ph4HcX$NvP6WM>P7sCf$)3gd#rj9B>d9@*SKc<44LEkeJGwP2L9=jT80BB1c(GIi~FlRgb0k(4GL$@V|Rv2VJk5C2)nylqoj<1nGxVs)XAApHs2i z8QFRQq}?P%Dr&sbl@Up?z`Fl zHy-WU!wwa2gpYjo9a5l#_>2mW)}m@L=h5#Ucv^QZrOS*y<(vBWrVdvb1z3+Ty^2-V^f1 zx;-g}Nio1Y(|pSsFt-E7z{9c2+YJIm6U+8v$&EKl33x08J1UI%Eub(?MjR$`o>UTi^2?vHfQ7z`Ww?JcBkZQ z-#OQ>xkChCoPxCsm3Xl9Uv%9`33w*6n{*-g6hNKYYu?iV`GG1@G3!ZD9Q^z1Q-Fwg zY(X>n+?2q)6_!qAyxOLzdNbuli#pxT?^tVF<%OHp{ zQ9O1ivz{Ya8MZkR{xr*f-dVKGa{S)g>owc<9Z@e!p4SZ@_%HwtHvElha>F|iO#(Ry zL0%W+U5b(JAAq^ph~{A~>Z!3m*%}RfA?QQ=+cT5fpoLNlg->nXI|wY4Pv~LAK3yZD z|DOo7!=B@XQc*8$iG!X*C|Wzq;SkHmWQak_OCLo4oVr~k#+cW1Ot4Nv7;$7CL%T4dDDG{dIG=NAJ?_bgL;e%>Bd$Kje zgMIKvnL3w?1y*slpEb6DGj*(8nnC-(u`^(!RIar z4juv$djlo>-G{CTNuzvImFbePCbPAL5nKO9kczX0#wV(!N;PTzeI(R&T8Fy;Qu{sYYy`F?KUCw^%HDx+-f3Hy4P5)mcYDAGJz%^5r7eK4a z5n^Xmz0kJB?{$L-0Ek-(%}V@7;FF!$?RDuQ2%XKqUYJS2(`%M_68gZwd?Sd21o6<{1eQFiLH(8ICRLsd9HdZo%n~E7{oK?Ei>RE-3k7?7h9*kOGeV z+RD6boS5TXTmu_AqnZC_NB{uI04dh-obXm7;yYjvho7Ff%!o>%kxP5aDk7yX zDGxS*1-{w>9TaUcv9>?JqS(;}l|Y1Pd@i$N?$jK5#q|$y4um5djAKkud4UAUauO30 z+g{3{n05>v^P5JICz&B6{)y60pp?`kp**UyZ$b0QxgZM?4me)0pVNs*mb;oS8?4*xC5iprYvw0IC&Np#r$4wdZu zwhZ`6M1KaiC=@NBPedRA!~_eua)yLSrJW6?hF`<}T<#GX=7H~n?CA5(>7yo<`{V{b zDb@%#MT7*%7TG&B0kyM+Nh6-nZWw`!TU~k*tw@y9gBJ!GE1yvZ-;=dplUh^M z6|tq!MheVo%u!O=KKxQT5EDN`ewG7w!>Jp0weNWKk9|>Vc@W{`&zPBdXccicT2q%I z-9?0P(A&50m4G0z_P?A0$lD;n&J?uk-x<8wStBy|>^%-6g$oIV1`F`fs%`>%robA+ zuE{)lF{PiK2kahK8ZDQ%d$cV9J!v z$ZHm$#%j9{bm10vye{@5;>9WGPR#;ImbO{CB5@f+VJq|>ZO?CS))b0w!9>wJn5&d< zR#U2+M>L4zX4U=J%^}OIoGXIKG4|xX+iwmqd{P#lrJ0Vsa$s}T*6SsxUJgqvXQ=eS ztoUst%Kmt20vS^6r#N$4{CmE1-SYd*TFX1gdLx?Nsp_NF3D+5f*~WQotqOsq^0`Hi zSt~<(lgr-->k6q}e*?1&^a3DVYg(4kM_&5 z|3OE|-|~Jh#l;UWCu@j=L={sXg23wkMM=;P>jX$MYwGkZkSB9%(2?o+(0Yzc_YKpO zg0Myrv$9u_eSY}@kaYWy<{I)*0JopKz{h8h^%zX+^+nZejGMJbkt`#zWvFkz1B%-q z`s>jtn|!$cg6`EeFXTzw;G}$q=|m^tF2qzmUMJ^8)2DDnJ%4il0FoImcz?#e#sDr> zSTCr(Yvgke##VxC#5I$iczEi{MITiQu=^@@@0+HZsMxs zS_oobh&uk(_oMy}G{r@;nW!I5fccft2N-9r(fAmg-C*hVd+;qIJOw$fi5SUw)xbPq z&;)X5wNbSJ)j8zAU0$u;X;3VBEVNXoqPi)%o9V!MdpS6?8L%YPdj@;Q$=G5;eg&J<$KvC;F zSuybmcn^3?Wc_<8xCDpc67*0CUHc2=pz96MTFf2tYTb^|7@B1Z@MyrE0>i~89;2s* z^LYVKyB73w58nQgx(qw^Lq9m#-#wyR>6Ei0t@bo3(cv|yReyWPJ$PD;B=ZIdFVW>5 z=n^VXy#w7G8>lAjjb>sv#kS#qo0!Ns#W{m^2%@b&vyYa^hEAA3ND9UWS$GIJ&kZEC znjim)BuDxkpBwVL`f=r4h`#6QxF}U?s!F^K@^lZY@!S|?sO+LSISpn8IpRXs#hkvI zN9j8~2b>}821EESJXM#^>4Wq@=W03qT={LBjqLQ(GGxI)LzP|5l=vN5Hk_4JI(OB# zIkgRY+|qm_O1me3aVFyT^Pu5xpGwheN$@imo`vfsARo8p0Uix{rb4E#3m^b7$GbBzGRASa^QxEQBWixOAZXeZmLfIW_D7aPs%L1Hr!XF*AqPT35W% z*;W?5OCVmw!xYYorkoGcixvI6g-sA!n@m3C6*;gRH-GQF@8zh6nB7xg{#WI`iPUUx zW$Hyo=Yb-7C&bsMFeFKJsvQJaLN9zlzFQc2dCR8bxeJYKga`~5_RT`!v)T+@oANqj z!P(WC!u<4NC&pX8Z0(zH%@hf0my~5<9&y!LzFE(9h$pVrU^0-K#M9gFuAYsy+uH9@+7X=)a} zJteFC>L#_KpY*i-r(gFri$|`{t!2(t&PWzNjwp4=CgEv(6s@?KW3C5Et}4kb#NOk) z2H!n-pU-d_t`gk!=Os;Zby`@h|6VFp>pg2{QszaqIS`T5x*jZEYkha&N^~TS%6zsI zm9~WE%Mv|bzgjGi2`MD2@Wf%zY;uQ(9@D> zL++N%-q{6Y7CrLI@)FecG?zIf>qfw}V_t@v7Hfs)sJl_b6Xy<+lcHow;wKjUla9!{ zkSoZBzI0oen|*jm+#7J8ce2{p zgm%SPN)8IKG;xaA%PSO~KlYyUlkY4CE!mjCayBDH>Srp+lbl+${KOlFjuj6=E{J66 zzr(<^V@GLIpo405mD?SzTOJxKamzLR%^{@=>lk^(#d#vnX3olsTCrJ!h%YS96>GNp zd#k^B=B>Pos$L@2FA)r;36`(i5;7$TnOApmy+65{xhUL&$O|d^QD8M9qrAzk}?wi}2yBeu{4v{0%qWVjCB5$<<(H z`WYM_yKf(0Imv!0@hOJ*fC2nO&w1@*wv>O3H|4}0B|kR%WCL^q$(!^+l&TPv7P@-! zmV8@jiPq}Vbyq^8nM{#(0hyXYTso7VA_Wd3EdMLiyhl$Im|yyC?-E`)0{Qe45_MG$ zle^%#;j&_jRm77kG@63JtiEzFC|_q+ex)57r}z!e?QExt!k5tNPT=Ms>?f3J;_$A+ z-)Yt3m_7E^LI&l7Jg=3?;bPEu5t5ZZ_;Nv^Sc@WPJUj2a$?YjV9I%%?$eQ$^3+;$2 z#i%L7cE=m@YZ2LxZGz07TmG}+a9M8sgZ~3ukVEu0)<>s3ooBbTQ|EpxHXt;A+&?$4 z6ln76FiBzrW-nMr@sJ<=i)xtZi5*WqeFAm7mn84kcf@tLGXzv8xZFMYKaC*tl&M8; z$vTy13?#)y>2%X7Mc}gNdn;Ut`gX0f^7;z;=`nnvl@4K6ump~2Y~)(!@2Vxbd2TJn ze^&8YQ$sXH5Ciy$qpYc$4^mA8_+>E6&k#twr{^LFLA?4xe(uUarUh{Jk+!Bks`u^$Rj`o zsM1`8z&5_leJiurZ}{8q4G=eU648R z;;c(z%CoqdO~PByF<)%9)2%!D(f>aqz2@#i9zBVk$ro^?hpc+>M! zM2_rPW=XiFgQ`1Zx*0e%GxIsQNmr|1DiDjSasQ{r8;_tBv4>XGFUb1q2J`$X<~F_! zxlYg@f4%{pgifa>*gB{fvBrNGIZr6OqZ@S*7x!NMHI=^wKRh-~Xe5m_pN8Im!gZ$O zDnl`3B_CmC!~0kX+u)8(Eq;&C@kDtG+H*?JzL=gTat(miPK@=HkI@WcrTuQu zole6GKVm1E-~XQYmkZFJb^QGm4_;>v-;-X?Oh%Y=Nz}N&T6s`8D7=Np#QyR+0b4b9 zlZVW3EgKK?jAwllCqR8*mn*+mWH$_dOEKCYq(z8%>D)mQjB!Rd^Rd-Hb+LJ*h#7EW z;B+3+>gM4#6umiGADBuy+<$}*tpc`CW(g2;2o7J%CZAM=eSLjESq zplKY>q{%SsEvt|uuB(Sf9)%5QK8fE8K%U_q!LZU1|NAfgtu>%`50D@2BfQvCxDvz| zbL8xN7=WYP@^8@}Zm=*+r4o}IK?ST8nV`qo7e7!NiL}|DDfa~|JoOPI#dFO#Uc!Tp z*>hZY`er;dYWhJ^KYF&y)^qXH`mfR&`pj+WYZ&#ZZ)s~EDxK%eW;As`L6bvr>*rI{ zN4gfIW!Mg_$a6LpTj6H7aVVBcK)n~VaNh>^hfxw6^kCNTZVj(yn$35PwdVv0idTBc z@s9SZs1_J}rcUo`qm-G`%u|`2a$U>(hcSC;MwGTOOrb*_vK&hw`(z2lT0jv1A{ksV`fX_euQawD zuTpfXNcDe=Tb83sMeCh;I=AF79@-p)%8~otOh!*Rk=Kt&q`aTr+Yk?_6kPLc&-%Hvn#t@ z3qZ2=teYLOm;w!lMN}c=f}LHx2Iz1LnUGJ-?%Ic% zIJkuX^b`YIt^#zfpPwlCt?nvjFtv$9!H-udLMw8=g8D+no(H&Chpru)qSnbrBjDyd zZ6jlumK9_Odd!ug8R-T_YboXi6|R{vacZeb7A5NyU(@u73J25qVJ`4oB3t1{V0P)7 za$%2$-XJd7arC>cA#+nNE6=5?qaNTSOwT*`TchJsUFSRjj{dgg@pwYO4h@i4ZNX$s+2QMNMv~*!Cx-|wIqT;MUx?}tw+v(wCGzyj3%gbC8f=3H z{8uI-r<-%WdBAj(&~SwA{v)R+g$grh2y8qj6<4k;U0v~}@xBK#{@2RJOS9aMrNuev zwB>ooxNhQC&hS9z>uzQ9&utbsACc&MAgiFi)Wts)wGQe(`R+P;&+XD!4!n7)>$1ke>_1q{-cwwl7#zXf3cg zJ+r^Cw&dH1h|dN&BC=K0NoykVFbO63@!oSqNlx3FJm%w7p1R3}t zpO@Sjqh!G;y4B+~zkS88Qb!4??P~@w9=Ukf*L0fk5E<3gc|9Jhb!_fpxT!0--f9l{ z`pZ)`WoOfPh^N)3FEbQ0Z-1xg6rs87ffBiuYcvs-z*pr7bz+H+^V}PqWW)Zpbnalf z2d$qefq%_zrKyQa@$7nQ?|pn_3u2>_+kDLsxq4k-29GNs_~pe(j7W>MEC(!;c2h zbSSX*IVAr`2~)NVFz(SyE3(oQHY!%s6y9AWfVX7q=M%RZk#Rn%Axzy?Dx*(n>aq0Pz3{>cbTrsx2&}}SC87b7&!K5@bo|9 z&8#eM*dt*Xi8=WbH|=|)V_@}E`Hd_g zXGr{r`_vo8W;_10HSM}y^*z_*>*?)Bu%2Dl90tGlOx*u%rB$BPD?ho`8CBiQX6NhS z^=Q1wjYg~)j;!usbjPjS)eA$bGKW#`sZP1kK7rC&1@^Chz-)-&_)n_mt{=I41XXYHFWo$POERvxEBob`dK{S3SHaV0F; z8Qg)FS1!?5zk;4ipQYr+59wZEUeBo=XsO`CqvCr7mThJT>SG+=JR9ugpDS=nL1!gfsb^gb17c2b@116E|SrOS2obQA$89 zxZ+e)XrF_Ly6`QjMQCx>*%y;nQ%sTND5sjmUmEN0fxZ)9%S%p8U z$@3n++%vN*(4c$S3Hsh6DQ67iraKSY`$Z92h)FA9crFEn@Bx9x^;d&eyQq(*4iw>@Q7+7;%-CC)c7ut(gKslX->}hCK zrJ$av+eBo@zbPGdFCcny@ zzho`=nM=J??B= zhnR9mIXSJzgl1DMwCpNLKPv=+Awf~OJnk_qyJAQc&8pb-qMz6dI>$K}0Xb!eCrD#Q z#h?uo*D?n8Y2mmy;H}rF%2=*tprYW{JBF zL=Wv#OAgh!cK60|Zfy5Nk_aqgrxj0n8E6~LJeJcrZ-V`dw^YPxb}bisevIx|u1u-K zcl0Qfz6L}eMmG>ke9K;jVuyl)UQ;P9K$QjK_P1laqD;A1x!x+n9+8G+GEy?{(GD*4 zDT@%pOc z4M8F{3%x4m0f84+EN(q;wCb%k-6?jEEeC7s^w(Bo4{|+g9_YcmeS(*+hmvZ_1#s4@ z)a0>7g~qjg05NLL-;`X^q$fBac|fKN#2}3zo1aKBK%cyo~FPG`8-_g+0HWDY{GuiROcabtN*0R zd3EC(Hs^*3A%JMbSCvYtT`@$a3uM~q+$_wzdF(3Ik%K;IEEAF^VVmxs@8z5Dre^eM zOOGq|&vj>n9c^&%IGV~_2jvKo44j?;XO&+6(Os96PgX+dpCKEI%s~% zGj=-h;r>QTXg4sfk`%Jqj<-LHD#yH#n+{dNJclg0mSM9os{G!=+#3Wek+WlO04=9x z+2D6Em5_p>cls3jmMF)+zicmodZC=>6*zvSJ|;!_6Q2Wfmx9DT9-lR`?C?4* zQI0yS2^@lK0o={^H*kQg;i2V~kYtCr-;jR@%QiF}FItFEScG(05i1oq z7S7$!YZu0Qtl9*Ep|NpIKXMpUac_q-)$2W}S|HxhhNI z*5nXAZ-as!h{k4H!Y0BA!kJq+s?~R@k%{Y&7nEC|0^PV#1%0N#o6FHz%)37J^@OV^vBw%bNxRg+UkS$cbkBM(wn) z^ra6{+mB~tT|Ol>Tqo@Mu{M(zL&7xIydYl$G@X> z!Qz&XeBfm0X8{9-*5)(;G6_m(OFh*a-h7a*@Ecpl!X+8B)AsjX+UZ;>3}>3jEMvYf z+wSW+{b=fG^(nY8N&6E63KO+4>6(_V8<`UWRQyNwUPvD&PPSu5imM z;=<}kEjVX5AO4hP{0yl`;ic^WG+6uxwtfg4*B%-T?1HBG$WKvFm6x!;tini%_~hR# zB16lUC~v@}67th=Gq-DEPkYvRZu-_N&q`eyHHd-Bjh4qlBVIWGpILhYm%@(y#i5R| z+UNXjA}u{e&?*x3M0u8zZQN$g26e`zvyDV_DnDd*`;ss?q7az$m}NQ)pUOFQe82j*#96@8xJ z{hx$20l#R5DH{1h@`PSz*+?3penkI%Cn4V%3;{PM`5S)C0N~8@mvVwQP_ZvdaNGtFr#m0@PQe8Ew|rQ4p1<9xo%SpO)n8X#omjn85Fei zTDXTu@1C_+(5PN*`h>m-8-F1|;xR}Sbh{A71oT(TM+s|0D{_6^bZA>%a;iUhOF*|O z7k2jNYP(l;-{{5(2Iz0SKU@Ud?7EmI8BfJzDU>k!8N(GP^GJ=LLtw4+HNE?U*e}#$ zs_fFBaaE$K!8o$_5C~^T{PI-ZT_>wyD+@2x5&6U9?38_d)u~YjGm@>hm}*_c|H72A z47?EO)Sg&{`BuMNhx&;!kxds>-1-jt<#cdL^0gCdFF{46+>M6n`l;(p+y+u%WsrMT1g$}_e;c7V10qQcn*I4_HQy}x zR&!fd;MS*0r*UNV)+wVjiHeJf>87i=3XF}#_lh>~wyaa_)vqY&EPf*Ng$-+_>HqP8 zizK`{a}`=0rL}Us_Xy^JMKH$srVLn2XutoD3f)HQbRnMPQKo45ft%y9LLsH0m9kT! zB+<-YB;OVOqU6uiNIY<~|LZ0q>ZGfO2GitZeh8WY^snWT01l@hb;*Tl1wp&S?cgFB zuKsVlo@_+TIMbAU{~}gTmJ* z5jbkY?8i%;-u;N_4lSqT##f3#XV>EKB^fpRdMyyRRvo8ZSxDt=Zh=baFWo2m2s|Oc2zp13er_y zwtkP~g$ZbZD?M9}`n17HZ!n>Vcv#k;ztiljH7OI;csez9H(Y6MxY9jW?#KR_XGb5u zaEHySbPKi;sEkA70T-=Qt|;AuKIamo6;DNW1hh;EKzzRcqYsDuKB;09{MJkT#FOy zS;mQXMy#b={~7v>>7F%Y`YgEWjfG|&{>U=~w*JU7-`GMUWw?lpKd&Ivmfrtc6Rnn> zQE1max2ssDuD08>3>n$fp13>gWIlWU=~=L2f+MVkXq4%t6)3#{*sYwO?7yEVFh%Vf z4*8E?vAj$#E#j1%>Hw_qTax{F)D1UBkNMt5gpDLNRd6~hI`_imElOMsG`o|bCsrQF z3N2&Djv@zZ;48`-zZt2?TAyF0&Y~exTwY6>U$?9TfsK+bWpQm7+SFUhKi^AReMH`@ zRlf^b;I$0J%pEPZBpu)ASm# z8kPB90fQz&1>;(?2O7YMpiBIDfz%hT9ZqX1Gzw2e zEW6p(0Tog!s(@56EnPje;*95SBWIg(2&4F%W$CJauB6CObR}aa?pNP@dOwAY$iIX= zB?=Us%3_tk7b>XRqO94ud>>zaoZ8Q4V$vnT7?;1~wq>xtFB(_a}e+sZ4eb+cjn z$ob0wbI`|(0p;qGpRI2bP&kp#`y2}~hU?=>B)@<2>S||Xt~;&Y_h%+SXFE0ZSpCqr zdjaG&v@=tQz=ZwVqn99g^@@0AJk5fj!fW+8Y-e{eXDgBfK^sRZdMxM5Hm*3b6#18) zqp>Kh=wx1FTD1U$nYrB$oQyfiBNSHV1_$SU#czzAo4fqjX42|hVW*Ax)rz3riCnxp zTb-Yi+X3g72YMg(s|oOIQ@)-rlLYQ{>?ASi0K1!1;uB2{2`0?~M^-U6*VMG+StC2SO!m*3gUrqXL8+TxSZn zH2i@$8H0^c(s54s+K9Bh;&E5bI@{ZiA}#hK3@3q?F;Ap*u|dXuOeq@(J4lj`V6+DsD}ml z8=gNNFvzqKyI&C{khfpB5E^yd1L9tla9Jcksxb zY&P5&Ij&!e6cGRfeh9!H?H>&ApKH?sv_y_qB(*Fp4}M^H8OL%k?Pok5OCgqjM|Kc$ ziNt1#LFZdf=k3N0V-&`HW6Qb$kFKA@iz#2xfT`zGww6{0Dw%BA4=2^0BTlH+auKf| zI@YMxt7jjm@3GvoqaX=r>lo9`@#BMBTEj;~zU%@}W|Lg@1Ba{;faW~?5uK8jhrq6d zefBYv54&|Uds?jV@aCMey;BIvHJl(US9oT4y(u*BV2WB82l3fE_&%_8{I-@lxDHf0 zBJ!40p2Ms28zNUUBrw+s>~S(f2{A2pPwH=(Z&;!=!g6({*;P{gG0EsGQldeRpD{<> zP}>$}g~^Fm)#GVcRzX?Ip*K(;Sl`aV7BJ@UB>F!8TnV89KYbACVqE%r%+PwGi3)Nx z4vH&73gbomY@`CIg{Qz>RnaSI3~%cyLzPHQJhr67Lcc0-lEGssGa9y!1}<1#DtTuB8gS5%6OaeokOJq zcm1swP#%DkBdAb#Ui$EvbUXhz+`it4&&&JtWH|NMQz~3f)*q+1$Ry*j7&^aUzuF zsEJwd6q?uway6wvCr{@J%+;_g?aUiVA-(Fa+ID{?%+cyLph=$Z%90D3P7^Oe(qiC; zR!l^7Tu#tL#~mvsF^d4z5|~nm61#Z&VU3odM~}l06b#=yr_uvwuIFQ}o11vF}NlnpTOqBJ~K!YixFGg>#9dUI*J_VNLGbqBW4+oeEd_#oZ$695{=#!*Fjt?A{^ z!*^g}9Zni2^U>DxP@H@MOoT8P{^9Jup@I@|j(!3MYl+-7>sYwO-W}mD4fk(Fq}~E> z+ZEcg4eaV@oq#e_xtkk=m0{R0`p_J5>|1OTZ{PHU5bx9~*ef6^83xqa`r9fy+W z*M~>HC;9X6V;d}TxwH#wLCU?%hw1v3Yy9T-Tl&KUqMiqmoc;0T&0G;8exo5IK?|LZ zw@7TyYyI;uouQh*bFi%!5dDS3mEfPh+hoUNBDH27yQh)j77 z5I~Fky$IP1{8*AgdmvpON}`jVSR9`5(3yRrj9ZaZ#?i!%$xfLhF z*;rJk08ES~LTLIZm^m(nk}CFaKF^Dt3}87mwhP9Hc6Dktv4($zQ|E_TMrG{D@BU3w z5>9we*HfdJ`KEsd=jFm)5ubNTYc%d}CGsn*1fUuE$8dW+%CwSuU{*7UuWA^M3G!mH z>TCh~HB-s8j;90j2eHASWhv>>;Ql5TX0Ndg;}@pXae%XVpKi>6YW!Es@J6cn+FOA2 z`=P-W$m+tC!@#D>uI^5F_4Pp zFPf=JyWfLMRe85vwTnfwqV4Kode7fqK|+=-suPD2MAq{Ap%?cUjdKSo?MY60r$I;L zP^QY=SiutgV=ubi?O_(fR`JvLW(KRCbQHJC%sV!dcFelgkKMytsvoW^(c{rc2Dq*? zaHQm)v#K?*jgbJvY$~W zn6*O#IXQ=kgc{NmAdA;FQ3I-?Hb~-6YmXuorO;}{DGFEv(|ef6pw-(2(Wua$npHb6^vIrZPzX5j(@T~ryp(dR zOW2|ApA1 z9h5pUX^ItYLQnl8bXMz4kcDv4^?l6%Cs~|}bHJO7Wo(c?usE?CopO#$`^{Z&QSHyx zeo5y=G}lGwR-CE^TVP}@2T>f&QVfWOzDJhQh;L0dbK-)Tl8Mgy8xFZoCDs}m^2~gwXXuMmX@cAdU)hF7GuMXUqH} z<;1A^KjtMnWhf)f?lUbQ#u1_4(4d<*#B`d(yO!z)#o6Uux*gJNQ>=^~*F$VD;;M|4 zg1bFl$eF6VY&j$NQskpE*Z}kcFnF}L_#R*L%8L8&`U`fBC<2~&tpTraz@>%nJz%=( zXu_ty*6*k_z|-8K-HJTrwT;Hr7opi!0(9$a5YS2tl*R8sxMf@rg!2*b*_v{O|5HpNC3-T-dqD+(;%zc=L?2JbzieSpNy^ca)_}uy1jZcGE60@Kv zxHhd1qW#uY%O4|oL(nU;BZLQ$3XY^lF8f+9n!s6%u1}OR^8MsHEBwALOiEL&)@(dl z_(fKb!A?&0=rx!Fn1M6yv&y!GDJohP2bjxy38Dm{XZYw^c66!|>R?rM0)ol^0WaWA z2a6HpwoE@%o3jRx?$!}o*=Pblo$;iY{@l(vSS*>LhTqCq0zJ9;$T1r+!3SHISW zw}-F;c+4qm5!o@n6C8w#VTPdKHiJ*lcj&+h-FSVUHIK8n4+{42HjU{*WHy1#bw#{c zB3*N7=v*;1ao_&snp%>y8Pz( z_aNp4QWXIFa~lDy_f|I++ijIHgunzZN+Lg&`r7O|*az`M|BVqbe7_uH{PnPHInprk}v6uSku6=kCq(bxD$5Xy_lo)pIXf z4w@v2w|N%;hy|vE*Ljr0kcm+O>28LbioDctQi}}&yNpQx$-A$2 z9~etHp~gV_Q#Qnwrpgjn)VAMCO#LAr>VM(-?c_R)``*5AtL^r^Ye^cVHiJqXw_yb9 zEvq!lUSFLBo`PeDjf0YBNB~j5h*|_D*xa?Ec&V9=Nc_GLwrk+ShZ}(4+KE?qh-a?D zB!UC3Mt$jrRAJ;=1>D1WGI5ATW~3y^mY|qW*jN_tJ}0_9tyMGaDGBN0d-;NOL8qXkrwze4DLorZ9lxN4v130SQr7gm>NkB%&&*eV!|QG9 zI+)ROA3?<^Xnb=(0flWv0y#8~%xBMa1%*)tD@<SGRnLuY@IIg565aWSuUGOswsT@T%*`-?vW`{l7oOgdo%mk( zOX5A9#gs=o;mW7`yZ4S9C!TCPB3qw}(3f(1PdM{JBX0pdp?l#rox$e9Xm{3$UC6=q z!5a~~$eSzIOQ!qSPth)>-5!Cu?F1m3F+Wx(;va(yHbxIh=W^;tdK08tBuwU@qc*xC zxxL!H*Go8@8XyR5o*2dz%BB-{w|@hzl5YN7Z8|QQ+-%qP?0AQ#BPSG?=76vM^9RhI zi4G-`@7rV!;#%+hrNZksf z4!%#4sUT&Mm032cw1+xa>M5n_&@@%H5XWvZIVt$UeUj*>_ZKwR1+62F7e38)`wiMpc0Zx@=PHyNXt{dYPKIk9D<1&#W6shy!>$u?Y&W@UHWs`W zjKD_udP{i39#Q|!NAlqfHT*aHUf+MM!G`w}EHrP0ToE_+>~0ggJ+VvVKtTXCy`jgl zMoYS{sZgsxmy8kWmlX8Dc$Z}4@n+tA+OwR3jVenqV`;LX2?j1-eeXa3s0+Ads%p$l zXR*;^V7qRmc;8)tov08Z)c7sRXMG=wnqRh_&Y_7gWij?xfDnGF7S5lwrdle1gzEi# zxnYP={wLJkeg}RSapJLuyiI>ILyoYO4^-Xbx2Iv?kCZc~2wyNrbMc7X3{Z9h`^w6; ziC@mVpJ!7sl}o^p7BvmO3M@Pmq=uF;QmRCNiCUB;4S^bZ7BYo?zh-)QTOj$4ly#Uv zD+}_QO}dBk<&NNXRvE*%o2+~9?(v*oSsyrfO*w6Q-qB8;z^J|7EkY{2@qo#R$5I0mcJ|F0=$69a~^w^UM|In}!JZq=mQa zi;om*GJp+=ep&seGA^&1%$qjn9J>$*LHOd*>}O$TwiN>ONyWEfBNQtw{SVz65XYM; z*4*758IommeE|iJzTk0&iLJV=8n`3}U%2;ZXpPTF_w9Fmun6%Xpzj?ARltMWx^fZh z3-dh@lkbHvAHqmF7dc5<`Aq7UOtnh5caAQW`h2ryNW#UPQ~iKSb;vS*pM4oR&}gaU z0AdI)?GMu$%IvWzGKBw6O%nR5=a6mv&F!ZnfpunW)pZA#;Ul@UxJYY8!;>x+3%E32 z^FiVPHB}~5^)*G%>6!!z?qTU@6B!L~Aw608=m+oIThc3JWmD1^9Zn=geV2yo*2lrFS}pCTuoP;<)L_<7a_Cu9c@%Z$St z$lkn4pL^XpaO=VoyVHGTsnM31-v(9NvNK58Yz2Gnik*a&eM81(E%3=)?PR z*Z-fV1?>b4R?0Q&QmR?APFIKQ`9)1!)RP193188_9|#@aAMjnOghR#;`EfPrvA;WX zfQ9d1xj8(Gek?6Pl3TxBwjc?k_RWR&pNG*9rM&xC*cC{D!}QANWvkFZ=Bq)s_xitg zf!j~r!HA_eG8k!$gK4&%{2 z7{aIYJ@Sy-r$yIvxAZqR2;3$osWCjBp3up@`<~^w72pCtUm1_{1kJKv4lD?rodAjw z8KQ1JRn)tvGIsFn2Xm!8UccWlyoKmVcR*!-CRBLLW}_n&Ta7B7)L!wJBh~Hgcb^sR zN$qoHHSz?W^v|J?R=GNly?$X_p6q44+3-jId=Xra#^-9?)e>FSrqYt{L#+0Np0%j@@%Eq{>C~-Se|3C; zO1uQ_Thahi5?Kwe?A(>?QN6+lDqntQ+BJ_1F8nbb43CeJ-X)weUsd_=_viBp-sSGLg;RkkWL6eHhJK9OqUbL8>jc)i`KZsmKmZ6#z-+D<}#0_03Y| z!>DeR-l87GfWH|WNGFd%=MdGGZ>k>f69(Rw@r02KE ziO5{p=v&kzW_y?VWgP?qi@s3Xb=od^JNeMxZJLgP?cK}`WDfi1t&`g0 zh%Q-fWOC*M+)yTmjd++;4_q*f!;W?0S03rOO%Y8p`1r?yef_ERQ2+Q7L;w>n)A}pn zbRu_dTr`961H$_dU;oMB8n2DxU&-x!gdKv}p_{kK=7`$gU*T+%TjiFUT?`7?ff@Jq zIZA*R!846~#cBevm6)YOeQmluXCcwy_(fe5Cu?#n%0IKSPFQxa3lJ;4Z@p zKvJ5-dc!cP2lvPi(LocxkJhSS*WvDSc&?k4?2^r!&M>%?FLRqdn_>HDXkF;UZ@FKl zJpwzi2BLks3hdW%IZu$nf6<;E?oEYmXy#!yPTTQY+Ufm_-{s&tMc~T><{Zlh?21Q> zcaKO@SFpvrIdx(6<|{O%`2R5W-tkoTfB5*FPKE63y|=88mAxfoW@Q}8NJwTG+4In` zBeRlyWGiJJ2MyUNm6cGTj7Y!dyZck!-`{vVe*ZN%=ly<-=e(}#`330I(I9>yp7leR z#4P%-k?XBd3mdTljl)a`Oq231Ys3?@#@Kq*WZ52VKT!FZUi1+X zi6k!`nisOOca&HbO&)pO$#K0e{7gS!%&z4qKUQ506TuS6CI!K5y~@TeZ8R@#+?04fyztZcXre*ehhNoYQ5W95jn|jcV@y zsWI)=N;+r6D?*^VN=F)6?>3&S0M<-(-sn+ znq20EwFGC+DX(=Ob6(KUAWGJRvzum7(dex85immi8`_`h;=U`1+g@s!zn>d~S-gv# z=Rda6G;^IrS}i^L0nHk)S+uzllIkZ#aTyod(!IX?l;IfUG*Vb9t%cO-YDLgK2fE4) zQnZs>PQ?P_McMm`ig(_O*9r7)LD44~jG=gC!`L~=qrO5K}iT) zLd-wYl}X&|sZ$<$NbiR`19np4z`R&M%)fC35;LosfSF9_9KjwD@|Ky$DF~5t%MIzI zure8RaPOY*eNe2_nWyFQ!;b-%Nb|R7<&xUdxpmr%Ns$}r)G#;a3 zN*pw~9lEYZONL+2;ym$X7sxfOFFmbXKEEH5{C*qi9xOoy-?k?P(%Kl!gkQ!@XH4O< z+D@j-tQ|&kwTS51V%vEGkKL4;A!Ib4Tl>DeMs9k8LQq*ZUSt2vNw_3OQ{F=IFhF7k zoej^s^H~>C*TY?Qc@iC_Jc#44Vzw8{GN#ZEKDtj$J8b_vGuE`{6gIm?yNBwmw>{-q$Y=B2KhJP(ZKT>eJBl z&6dM0_BrD7w18Bb%fr}-UCvi|b3cp{0^Xh8%93|J4tKuFJY#ARrzic?hV7g`H4Q;a zLJIo}2E914v^|a}&sz_(?mitp!bIx-)X%y=z=TLqW!Y&n5ZA-~hzgINUTm4E!4ZU8 zOlRrxZRMB;_GeDVzvuPMcr^!Rn@Q!Q`eVhPT?aF)VtxB8J_dbzl%gziiZ^7R;=FjR zKmvKevax!e^3S=OXRZb_hgD!+WGqJD^FqJetuX9x`8+Gn?E}RT2EI(6p|Opb{5W3@ zz$gs1=3aYbE$Wvd60I2aY6eO#YX?o0DEVIE=1mQXR_kc)DZ`bXs)^wF9ek=1k*gJ& zJ5*kZ>sflIChYx9;(T6~YBHGQQR4R3`h~gHw0?0Vcc7nv& zvD9~`+stGe)b3=l@OyuiWRQBynW;i9_WSlB}9katpp1Izp;&^EiZ6`Ppn~9^&Y5zQpkZ zM_8Y0kMK#qnEAQCmCYyF;VHg#xilW@l}LGt^T5U}!9&i>GVW%a1KTk3$+zR~m2LZw zRdZv`cel)ZC!%rQ5Zhn@94U zr*!e;jz`i;+PpeZ@`@c%z5(N0VaN9zhK`)ZUyZN)0TD-!_$f0YITtT02GUKI^i5zX z)1$q6^<&DB4j`%6WJ682!qo_WJAce>5!?`IJO1lo8@798oZ(0;SF_KoC3V2e6Akx|j`qKAGY1 zCq5*h`DJ)YAi8$PX58O9nb9QtY=oZAm=a9UM@Kr=8z_PR#^t!a2+dwncTXNwdw)DO z9m1#iFDJcEVA4eT?aD=+JFfq5iq}rzNi-pJYsDKz%AFjx+>f&{zaSVk&%9;$=1U1m z#2cTcS2RsVl&l&q_odmDitQ|Yr#54g^NKuCRdCJOHy>M+M=Qm6CX7w1jITOKIhjN< z^t<06m&K!l=L*2cFZPmEqlQJL&K6mPtTuFki{;=@r?-X}4LHy3%OF~Hh>*oY%@xc^@;Z3A%8PKA$A_ynEiH}n6%SK1 zm3*L4jA5qut+G1ai=~RYsCXBsu_ofkaRvd>v|Me*?{8&;;rC@4Yi*-IfE}Tq5|mEw zp!LQ5o~;UF%$s!(A+W@smK#51J@oGstE*W*gI10FmT}AS#Ax&I?CTtc$e=Sxl>MKO z>J#hxw@+?#0q^(qC50nwSB&4v&wv=#tA&;~ptp5QdJ!SxzeBL7`8tPX2{!fYliQFm zar~rr^xDoVu2?Tt>N6Zy-U<)xCt>;sN@Ac;Y$=Q3?ccN%%;PZS4@nSzdiO`lrjGlu zmahO%B{mSP(~KQ=Q;=2BV3ZmM=)~|l`gc0rGfoMc4-*dxtdQ1+b zH?d4G3BL8U1V!aLV%ofiiE`#RUxrDcbbL=~+T*~3nQ}~sP}fz~bLJN=G?SYY9oXm< zMxV2UrZ;KB1!#Byvi8Jqs#_8T4LigYgW69?@ zQK(H$C;9n@I!TPwhpyoIsazzBMa86!cyYHG8#QI)pSgE$a7js<#AFRS$BA6rgW$(| zuv3dO8#F^DuAfEo}%Wu^hx2W?3n&gV&&QS zPxUFieH+&b1_a*VW6M#l3IZY@=0AV_U4N2%HG(9rw<)>1O^Qz(@`&ba0xS^2H8I~$ z5UFw?dSmcoD^C7Ie(aUR7*0 zDBkDF|1%VC9$oCI?-$I#*_#j~R4_akdQ5^~qOOo;K`N&NwXPa57v6S$Eya zPB@;}%+NSERkVcImYB6|1!tfnr}C0=vH`xUg?l{eqfo>!!vQ=0VEp5mq8ktVdI%-t%3|*raN0zROu_5+iwNo<6Nb&x~CD zXtnjUaXrisna&;q2eBt}IBx|JB8j+F4WSIrEoG;ms&1CNf@ZwoINCzu^{5=q{qx{U_=0H zOpr^DK2xlqUA9Z*-bP?S)O4h0#0mBI6GYTeNv8&H40b4mO#x2VH|L6AmJSo1m(ye{ zY0(t=Usi*mQEwy3#?C(RQy2@cRN5gjlE22?##PMu$vA-~Epga$P*SUW87UNNoq`$b z?ws{Z>-NHZgWFlQzWstIbiD!{v!Xg#CxcpiyJ_*X|4L=5{!oSDZsqfB{3RWE)lJQF z8d6XAo=D{TL8B*@OCzS6BP}m|CHlP99ieI)oNk>3-qb~!XIt6&E{5ActYYX?I7`j~ z-ZrZvlQ>j2{cFTyt*bS^qT-XFh~&4$Qf;tl#;n4j)X$zer?>Ek*Nnc+fgbvD_-dXU z3B8aN>-`k&63e3V-Z%NEf-*d>uUspp{e%sh`)&YECZu~eb={(_V#$Z*o;Q+PK0K9T z^f$L8KQNQ+(Lt*hiVt%vxvd$ z#fQ+7=^&mEAsGEngkglLT2LD;BIiZxZ`z`o5&~tiP6)Udf5KEtr)o_`YcC4rug?SB z(_=7oA5v90SyZlv?y2kl1gTCZ*D9chX05GZ)$U>1(>qSMd@Ryr$@wK_vMn)RnkIg{ zWiDN|?2Tzolc$h0p_1$F;|RF;?yxv^Ge0Q)# znzB4r9GeD&Obf8+jqDk>EX#Vgz%J|PEd$R40^P|1t7q!Fx4)fc8ifG6Ucz?{f6}h{ z3Cy#V!tua>KRz~D|pCBB6X*( zQ@bn2D8-@``)*FAdWhN3)5uQioRzI{T3C>TOZWrX26a&mo65s$Q`NU1oXiZMjT&}i&EIrEzjZ_j@IH>-W{Yv<=>Ojsij2;9p- zYho$@rFbY_j3twIdH;S5`g4n#Rh~6?UA;@{3&ju4r#GEU>7#DIscR_wgmgS*@**xL zmr4?69Yi`Lfi_il7pSL7laftyJQ5ULDZit(bYhN_kW;2ASZv0v))C#C)7$0zRi~p& zlMvb~uj?GGZ=W^HZpwtCkFbi(*3Q$t0CSPFtIJKti|QpyhXZ=>Hr75d-xlS)Eec9F zc)1H^aRInt>y~9J(vFq7vO&1VqG6$TZ~5voLjEDT*vGtHlnlLPNrDlU%`l==v$wum zJkRTRhOQE*$xjg{-WssyJ4j!q@UkFAe)1ls7b$E<;ss@Ng^a$JTsw7A0ivItZ|^^6 z(z*;IwL)ipm9b{UG))PVjD8sXv87!7GNz4Z?;iEYm>AwU`SkRIEycM^ZU}B@^Rr92`cOpN(%O8EV0~}b4;ydV7Azz6 z4@XeeGa+6Afq>9#(-(V&#`{&$Pa;fxk`64nfxNRLfFTkW%M8x|D$}2K6jO;`(BOQ+ z(+8Lo)>SH(fx)sPX$?rps&>k~qQ`U;2oYYP#C6eq`a`)|Op4zl#sN`avc5B^c5^h2 zCbjaSutAQL1iD@-qn;vvH5Hg!e3?0-z*kT=yB>o5tU>1VnU^bNvFog%q}GR*ch5A9 z)lGZUV1xYKZln9MGCrGH+{5Z6d&GL46B4w^m2%~aI2!K`SdWyDW0HxR!~4$`!x`gQ zW4ZxKcBUt`eYtaU04&rA_2F0kJ=a_yNfmbQFv^zT%CaL{O5C*yXp!dB$C)N%$naD3Q;jS@7r^O7 z;4KKC1ds&Gg^TrXedt~Q*y~kG-Jps$0ade5q*dU-d|FP(`E-orgzSM*F`O-@N1An_ z9NA8R++7@+Dx-lpB%kded{ziiyW?y3XL-YUUtNsrPFz~uI?t07zQ~7!BCNvbLoKeS zfNXC?pjtav#ED)+G>@EQIeE*G2(Un-k%J(F0Ko2vD(byax3EHIm^4D>aF=%Sg|$ ztsabG(v)})DAzdEQpjv7(YX6MdSC zWCvCu4_vxJTE4O|9+%Un0;tedSY zHy1(c^F1@o5!TD9dyn~R{0lC3l9-%Bs79S|{^+FT(b7KtJ>gd`q!uO#%rn=k-G(>1 zWGg^O^QC}kkX z2$x@_TopY)Vipd6Kg2l|h58u&&+WLyA!?lGTK^Rs$(N7#F~D8x}gMKfdq(DR)LoA3)%ZoA1WbuEdR%QVxQFj5%h1QJaw zD3(aM-c{4iy?7^Q>Xx>vcy|>%4yDYv@rj-iR6i^dRg0w)@3@V~YJT!3Z1brlIbUjD>#c>|x~gzoQ&L}%dybDf z>Br+{{2hx+wU!go_=^bC*JS9q03W|%+oiK4M%D2!1G>d7MxtB!lS$=~cEJGM%!j5e zVIV@4c3{h#a1v^VmiU_K8&odjUs5yEnPSwH1I)HT9 zB{?1qlA1&eIUb|AXGx?ILq!PVz}dUaH~;F*iy_r|yWCcGM)f0nPu2%;WoiOJJm~eJ zD^n0RQA;1-GBYetl6QU2_41g5OQRb54y*$E0JUkcC^}nz_&IbWSrMVI;^tDR3#^8D zy5_`gx;8Gs>gV*(vriQ^DkU!5Xk-dbzlG?V#{#Xh>h$fn<9ieb4o^m{kHX-wxISb4 z6q<`j(^k~2R|#Mh1KIN5pfgQMEC(}kNP%_imJJ1#*-!*8fJ=W#HtU zCtNHzexwVd%FHX+fwv+dNDd#yF+O=1=@Bop*s4aWWu}>+Kf8P(c^{evv4E6S5=gn) zkcl^sGlmoA@YWVbIxNuPHaH+!Z|E5r(!18j!O`J%3hU;w2Nb>}Keat>t0Sel-7kEb ze*%4-_*edzHC*d5ZsXg}H!DNrq3@S2Mzx=GqtX>D^>ZuaPI^3Kt@=~dzsCdzVDm#p zlY1lEsulEU{)uo+Z`xD2PsGy6|GUkDQDui-K$E5<3V+8Ru#?@Qg~SJ84bKl&YFUU$ zy)IQ1ZUIC^iD>i%)x)B^H!A~2%)^N7U7GaLb<$(>#i&8v+v?t#?nEd-@?`mlgpjQh zcUm(8tsTp%DO)ssu5m;-@@TrDq}muOZ>m`&uHNr$YIg*-YXZM_)(Ep2Po{yb=h22% z11O3yN^kQ7IcKtJkPr9aN~`2f>fduq>RgS$B9kZ$FC$nk(|puHGg%rGHL8Zv#EAVb@j1Q zwJ1@XRhd-Hj+d)+mk)V*k7x$1*oex;yYB>2*D_z7?YVPz_t0)nrg(gCz5kzEGQ;Sd zY9CbL`szgrA7=z9)dh>7L>%c-&pzpS9LeAN?oZ@0%jHLD9W1z{E&l+TJP$w4LV&EW z9<%ZVdY8gh1hSR`@+HvRl?<`4I5`0|{4PkcSfm$9eSIhUd3-RVF}RCy0?>;0$VO*c zPi62Jpf?l<>!VD@D018gg7EP1B(}lpV^dj9Trkdt2K>>20-Q2ei72p84yCFs6dE#b zJOb>@tRy0g_bKE$|5>W}XBTdK&Y1h&+QqMHDS>Kc5sa>4Gm4eU(~T6uSRj>*?BqDpEIb;N z#Kf|nR8ISg#)>UsrNmRj-9lZu)Qx$%UIJ;>#5h!g)Nq|gifi}QpfOh7u*`7jCs<`N zm#jP}mzCVgx_uyddH-E32SuFi3LDO!y7GYa1H44vPdiXWLaSbwn<6~x&UlvYzsQI> z11LDoo6O_KYS6|C>~+FuJ01@QOB_%75At z?^Qy4Zy(@<4y#RYR*-cb+`V+a{LaVw<=ZFc2Lx~E>NP(lEYpozksRT2qkGArek79l$=2Yp zr9~|7s;Tj7 zp1KNFUaKWxah=!>;Jd-qgKhx}Ibp}0i*E@|mSYkXNcEXb3nWxFEOh$nbr{3yo_veV zj%y#aj@N3IrYA&k8=q}mLv(*>Cxw}yrJ3&BAO=2D0T%6k*QEVl!`20rBjNU_%NIAv z!~wV#wxa;p9mr7TdtncRwKyNPcrUc+Q#Y`|Z<`Ze;q{aZbD@o@I>cZr;fhk%c(L5^rW>Jr>MKVcZ^@ZfWbHl1PhmcT0v#(es7c6 z#XGHLD^(&ywpp4qN81!0<)*eZ-Pe2d2(~a7sc3tPybt{Qkoh!lt6xT!ch%2Mwf4c$6!RN*Ovi`HAi5|oXK_5|6iI0(@6+64W-^QzmKABVFVIy zJa;k=yhpI1JM8X9bMF}Zj6aTwLWAhE>SMXByz|ugk>F%XP*jZwh~f)WKVlF}9H|Y+ zo7jHRjQn?mmwZ7 z8@aL(T?G-fOem=Cdf_~|JP|Z00{E*8%B)hqxxQ~dVj6<^;}&7_TTesk`ij`AP!@Hs zPf5$GwbAl_?WjZ={I8L7BqG(#PKoIk9$pmjZg`WcI6KA(sV(#JiYOn9<$BcOKu*}? zf`(SQs!$l^U0j^YgfOpX704(#LX(~Zc%u~tjv@n-yCGr$`PU47C&&j#9?*bKwm9dt zI8~4O+8>-*Q}ydVVbTzG-N}FG$nrnJ`fq_9Xuv4%>%u7OX~hVPbgfs7l5j?^B4(lQ zO#$C?PgJO1$E3x`4y?lts`Y!wNfH}i2_1D=2nHD6E0+m(UPlqdfX|=pkN(+Yc!qlv z@Z}#bH!}QjGta-ET7&Ca-wAv`DIhmv0i)_i1EulA9R!yav4R0NW^9MNuicwXKv5=Yp+3hAL!gei=AbhXyj}u&qId{#Sg-!M;D&(iaQP4$im}(f z&}NASqT`*?Mpt&a*Va6>J#<E3LUpD&N~DwoqM+b#-pAU zSHSac_vb?poJi$o6YPJl&RL{&n1B}bpdr|x9XEJMMwBD2c%40L`L6s^*1!S%!fGfx zjDA}`c@h?n2&M2nWE-MCvRJmOR;up_sgQs0C)nsM+T=I6TQ6Y1Yg zP{CNZ0`enDI)9wQ1Hp)|y{z8r8?GJHofbA;bQb3>mfblnaPRFqqb%5=FH@JE`ukhZ z+&grjfRanr%Bh9^>nfml?;VavnX3ZGu5=QcqO9u-Gt??C3Fr{vDFCDY-@*qL0gIB}J2eyqD(0o4e9dhPR(52+ZHIBs7!O-Mh1A zUOh54uPu04wQSR=Z1ar!U7j@IS7#oXWn8P|d2+vgQ}NvF-Zwl$jcHyFsTJ!?+AZ^^ z%)u$Y@7y;8%=Kuj>jj+G-=!jcxKCGu&hfG2MC#Z%WKtLrp^r&a*iU{?0(dc==kX6z zokPn^6?H682-SzudB zw%Xb)U*;a*XH8Bu271yF^>i*#CHStxdkxwDiHHt8`jwE_Lpjmg#2$`U-hR z?IQm^R0;A>59s{b|2`BF_)K+*e>=3teB7?7)o7hQ*)aD+xs6v44i-`c6)IhQeXKL> z_bD=-K@HDb$HuY&AMV8stvfrQH`WRK;MaF5-vh&&si%s`?UrPMZH91#)z`-fO3xP) zwIbIges9&sq{pdTQ9>U*4JmYp@*!C8js5+}2+9}n5n}f((wcA^W^aVQ`>v^ifjKaf zRI$tF8~*#5Pf$l_i&lKt=;5CVH`4lZfp!0Ddw%;}2juOlbwmg@p@ds!@>rng?R*UH zI^vPJoEw7My4(9EE5-ibk9aPOVlJyJUbm=N(One!)Bol*_CS2M{ej)T-jW;vo2@!E zB((Qb+U*{0HDcPtC8nYwF;s5Q?`K9)hP1WFfT+WuR2%5=b!T-u7 z;Eq^a0sQ1ISKI|~RQGMZD@5c*g_F1)nQh;bzd+)2Ja3OQ3&#w{{Bci6olFQ)Yq_{T z%ZO2ZfeL-sc){#+Kp~6_5-UIE?npEws30?Y>s(->!nean`8+&v0fTr3TD8aH|0IOZ zas57O$TQyi2Rt~b>VvDm25M=u>kP#<`%7Al&(29HjK|q%27tRiiVZ6k1FlH z%sIh-;5N^Rg;sfYoVb)*6sp- z**X8O9eT~j43}6gHUzs?E)7jOcEv;&X~b?C3N*s6ePxVr9c(=$I$y>9N=jBVq8Nff zy6FBJ5ELKge}4a&OelF_gj|)z-z!0LK@hG9d4ny*e`=kX;o{R{nPJLbFKt!@TOI1- zj94c=;V~w5A<$dc`%GXaWCZZ;ro3L@hM|}SQ6Q0Z-=8q`*R~eA!B>AHv$V-tLv7=pmXR)+i6y=K)+r2f*PmMGTzGDGz!g!`s% z+@E-T#{PEy5Rcy1g-=PSUHuESJ)r;_t?lrHkff6Lu6I2?!_i%Y=EFszpN9W}ZuZv`@Zkmgp1ZK0Rp8=wKe1r% z;3n|r_6Y04TZldNJbd5cST@ctR=;AXqnIHxS+DR2Nw!eUk#|!M;8|n-aXQEyBGSKd z34XEAA68VzyW#1jfII&==M4~Sn;-qS`PcF>W5F-IiuOPU9i^F+lh~f5Ngxk)R9v~k zkNNZpPpg{=f$ASj+0w7&(4UbhfLHl_wK*f+!;8>8Bk=rLc+~*}ThMmsoZXv9?Z!}U z6_LvgdtU1Q_^Wex4?kPol4LDPA&8lboAK{KH z&%fL%c<^ZW^cL|yFBXnU;D39x$;(8@`v*s=IuS#McY~a4!Xu25F_E%nxQ7qO+OFmD z(l!MXKN$L*?r}!YbG`NWM-2De2;q7CcIyl9leUx*!-MN8~S>) zqa>r5d67AwG+B?+VakcVD)9A_CrM$+EwOA3zZd(P9vG>Qes-)GzyAde%m#AE9?AG? z|NXW;;_XhakO%R4FvMo(1Stvcq_fM2bJiX5Ccy~xaodVavC~B5lfCD@I$fUn{aas& z4>%nB@P82d;7}t;&@}DupMf>fI`$>{)#g2Ltvngm~Y#kgK>c5%FXbcJ8dM-U;f?|WSNYK;Dpnh54!i~ z)h_shSy&B#llZQJD2?0U_|k{(CJXN06caZ-C;j7{ON~%>cs$Dd&e=`rvtpatQ;-H2 zAk56Ipj3^m2Y5pYvflsAXaBrOA!4(%9M?JFRs@mkF{)=52i;v9L^j_HflWFVw%)@e8#$Acq@9Lq}F`f{^loX*EjCn6^|w5 z6b>9BXgjF&A<MI55YNYc+9P+_2(9FMznIl9hNhAr~2pk zs{VlMcK@f0JC=G~Ta_Sd<{8wZos&0lL;b#fwdTyGr3KeAN=obpW7i^-; zUtxjrldM{SwzYV3zlrU`-`WWfJ#%1Tq-(1Ee#h1T`GCB_+_6yB(w}H@{fhF7pfgRk zdy~Fcd^Vv-48~;O_!JY-wu8-y@^>com8z8w^iaccxEnn7sBPR^wIiZ|Jag$(pI z$#5>w@crh8F9pCs8U>S<+@G;otq`gR>-6^%k0K5^LhEY6-%m7!neD&846{e%o zPfCFXkHnP^&-G=!Y~aJF;RpT=I8-%Yr@&2pAYXa=pDXdP0ABO8c-q0gU-bneNw}>A+z0??^lZq$)&G1BFGMk7TM_?x+!yfGQzhR)ah(Qf1@tDZ^{f=j zr62ii#Gad>MD3=`29{jlLy6#r_d>>xLSgl{Ia4K4MjWxg(%8jUpv!h{8xS0w`XW_W zmUl1*|`q0UzDAH zL(a;wgMR~#f4@88Jsb}qZ@Q+lN`GSpc(Qpgy~3$B8n-j%st^<~D=2mO9M^mEeiwvN zr1n zv`2jfH^m}i;DC)@FNc7~bywjp)$iZyiKZ?*v4T(I(GaJn+ znjF{M@;TYy^{8MDhci!KH}XODft0#xLEf`x$sPnc9AWU(=PMt}J-N5s^?MQg<~VY- zrA^;_44w&uSd}xvo$4*Q_Wm20KgJ5`v1j1LcFDZd{#-5OfI_G&oN1QUcN&`12!FVx zqzS%9(91+2ZSXkEdolY|2Lm+j=}4K`0ipg~98U`Vn>5Trl`V0AC+R{oQjjLSc0`h@ zpdwg=*)15YslE+J*mHA9KSQi6Qn+u9gD`^rr4oTNg6L4Fpe9ZRVwPc0ceey!Znoy0 zd$x6=kP&N_@m#S{H68m3)d=H2cv{2b#1`-`6Kzf7`%5)8_w*xKSC;%R- z6OPBsQZ{uv1rTck4fh}7N{+pD@b4gJJx__moRn5U6|r*pLr6d^7^y0Zj%wGk=J=06 zD-1#504!OP=U=1q?Eml;%djjTBN}FaeR?qGuEJ4$2Baib1O-bvwgb2xAPVM+o%Hd8xW@Kc+V^+u+|hv37JW( zVN(bx7UzYG0@HyJ8D!iVlMc&ZohB||bc=Bx&=fI<)`rRZ+5J3y5#KPwNXxqS_jfC* zo5F8YAkpO}25lOh?8bnsKr7@tfP_|ECArK-0}*W1kMpemy2vX?i=>Hq>OaN{$ppa5 zp1A*>au0YX2aBHrGVO)Ytzx>lGWe6E{vqk16K7%EkIx*KFa|;Dv}D*6c~0h1PU&%? zqoPz{ywWcae9{)cY|fp8!`=nuRSrZsrMORXrw7`X3a;OSVZ31{*np{}7DTdY0tTQY zUh2p`2wH?yw(z!|y_{`l5cAWn6% zhpbS8v}SlNC3~IU-u9Y_yJoSiV>F%nsXI@rIS%&)B33@|j16cJb^#IP?1tnbW%xIC z#jBnOOt$!5&sKg9a2e>4;DEBIauvg+@qX)8>f2FsY->lW)3kZmspCj@?VeenR-lRE z&mgOZRr#|>4fFXR*q_`W|9qPgDqRlx(ktc95}DDXtalMplmbVqMe#p|h!@6wLYv{S z!o%`O^Or7n)TOfB@0YhKJh<0~Of9#yU`0ummN@+QX!#BiFw6gmbhHp1)3rs!$nF90 zI%(#tRN9JZ8G%VxQttJYvv+5m3$Vs3z(bw@%#rie8uc}V5DS`yLdGAdNuXh3e<*bq z#4((A8ew{cM1t#}wAQ0ai~cpb24b00#N{Y!k`!G*1F;6PIqRATTg0yxN96?PYgo>z z6TesBkh^57*plX(0uYl>%hT9z+enpG`V9zB)eP;F*{Y!ZZExH}@VTl?6HlGMkHuF~ zn+bU-f}lcQmvt6&WcaT?YdBc{Nn2X#)A3`^ypO{Y3^f!y)kfl!Uw1b%;|hDS;bYU` z z(h!i=uh}86vZdbTMu64X@d=W112&)AH;hy-b5rT3V1U zHVoTl!#46}qChh9lqe3*U1w6At%vZov^2nc$t>0p*$8 zkV=}_fzKacWyoqCeRp?}o5!B*jqP98z`8#-gg^csa$-fL~ zW-KBavZ+Sj3XuQCvzJ(7Z*9W;>>D%(c8pgx%yT$sO0ioxt?KLa`7{VtI+kTvBrw&H zYRNBO2j?9NE#&I1qO^Q(P~s5w_%N*qY{$l0=(#uMsd$>UiFfSz+FBNmEZ?n&s7nE{ z2%8Teil&5psM#o89gB#~=ocYi)7YWQdv*b@>CU%-*YCS#X@q(486LwsK=}O!cm6Z1W2SO{rcDIAyjDWr|)I9 z1(IJxeS8}SD=;HxfB^~_Zadvb_@Y{gPj8YRD} z5K=Y`!H}2}zxc`9KD|s{xj~>q?3AhaK8EEI@xdb$qRZd)l6_a}_$Ngp@YjVrCIBhJ zs-;kR8g-8rVnwH0e%EVL-|8*Yd9s4Imm>&%uH}CJRug9Tg;}^;BtB7kP(nj=$fuiH zr+b%pk~j^ecyv=_i<3wa6GVk*G}21_gcze+stIs@AAG|y{8EJjekh+IYJeKHxxx3% ze0BadLv%lFCv2uQpWQT}^+%Z*I9&sJa9O7E?}!G!ins1V2D0e7pQYi(#H!2U9f2kE61M z4Q-vCx_mr@(#H)@=>z#1V?3yG+7(Nj4WC-7zjn&IX8Z?(xP^>6nSJWGgN`UiLN1xMNTM97L-@rZxy56C#PmgT}Y z=pH_1W6idweWqWuWQ;PxEm0E(ue|WBxeb}IgneqIjRno@7S@`N>WyGmuDJ7jmgM{d z!n8BFFN{^Dj86z5lH#SIUw4&9qtEs#mv(~E;G?r6E|dsrOeuz;lu8vKAa4X8xNfm@ z@C;bF?N-?KzJ7hQKs>@7NeX3sc7Ii8BAg&)rPJtl=6zldr{RClhX%gq2_W%QHT6k8 zVGWbyfFf7 z)bw4Zi*ZtEac21$ZnIIQeOaiJ`gX3;9(?h!kNO9rFKb;k6rLp3u)5O>{bg{_v@Tlj zw_&2fAzmIrE8o&Z(DO@Px2scA6e_W~z98I9_dSLOy<*Dgz(*ZxnlpG2$mYqE_579O zX=2N<&!eq0z9>7LC*YzCzk#-uCJF!A+mk4f(lT0I@2^^qN&90|RbRoj`K{Xd4avw$ zegOD)GSghTt~8K!0@;VzCkduY&-NY`=*KS{)kNCgt7V+djDGw_=}j5t52q1R`%uND zzqR<-Dt*bNlviMQ2HXdI2flqYUp4$3gj-I>;)3-?^mlLh>n~&INCsN2Ls6u`$|&RQ zF0X;>yx3f=S@q4~*g^5vS)h=SEh3&!+h2FlbA<(E7^RVd2rM;2wpS9TQ)>YfL;wDJ z=~kTuIt8nuxZT`AB!+Wgc_)#dC`#Hv%eGqM%b2C4b_S!G3{lo-;DMEYdz+--JbaxI zlW@+&^PaN54pK2oR26wM3jnBwHb|NOh z6S||O)i+CctvI)-CTSe;qH#1zF=XaOoHt<|D_4z%`-XMnG@IWv_!)(aW_>0OHtufB6G0V^Q6yRgG}9ef=SZfNVP`zR z{WPq&c+7G=icBwof@c7ul#8xsy>Wb3%E{pc5Y}Sm;6F-JY+{*%$F0*03Xx|$;ev(B+=mct>G3b@c%x(K-yv$O-X zwY->!|C*KTE`!QTZQ*5IS;1-&DWNrW4bsxq2Ypn@RYqOO4k=a2RsnCiFS&purY@aCY?UeH^j6Y|Q>Cgn-}xFFmT z%nDvun^T7U^5X+7YjqC&*;&;`a97H3m29ixM#nRJg#0$F{uPD$)nfbAec3?`=Os?A z44Fc>aNnSit|#UrO`{xCL@iJ_nw#ij9u1_MpbhY+rV+7#Ktl?b6GPL7Rz@aIUb(w|;&_U)knq&$=w8tya|k zi0O_Y!{_a4HY&N%_+@i+JkvkRnuikVjS0Q6jcArm813&p0$6)CwQ$~Kf~bK|7h|!B za8~xFLQXzC$N^5Uha?$ZL9n`cOPD9es}>>DIab30cKn&Fex|Tge%;;rCo-y;?bfb2 zWzwaq>;nXwN~U?ycqEL~x3d<)88baKt-ig&Y#f;(!;9NhSaVUSb0gNj#qGm&W2- zF5rI946wQ$N?tjEx4KDp4w8`^iI;}bJsOw534V!H+2gvNiot3o@_L)JVtkLyYtzWC zO9z_7q!=1NN}N2Im9844s&S_lbdLp%aY-sfX&(6ZCm?&jB2T8z#U06Y7tMEElSTjV zf`MsIN@_}f^Ub-m$`9H=w2D7s5;Le@&Oso)vmPr{&%}2ihcbc|V4hg74?xa{Zx;tD z_4Y|$1|qAvG_l({OnrzjQQe+{TN+BJRNmzjQ3_s**ki|MHd!tPM9ihuPos~$w8cwk z%a+k%NlM8#9SE+POzj9=fn7bb_JOyM9=>%5HnL^oY^K;|4>Cc4zwKC3I`)WL3SXj? zET-3rlDmywPl0=vnNRlRcOOsTqHUzAM5Sw)7}Tsda>_EYLv!@WxcCgKpL{Gm5QEVVpayboduf}QT6yXf_45uNV8fAR+`qe?o z{!~>{^}|z8jhcOi^;25M^StV}(Y3*!Ex#hL&ZzzjL}?lD3Mlc-i^4@YVm3MXZ-I-; zqQyJqw67_g(>HM};QH+`9+4z2TRX^OF%N?3`}!;()` z(J87{yI1@@RKOBfpPzE#yXKQzR_A7r>APp5!p)!XFiZ2Ks1~-qgv^$vR3S1^w^PX=9yrD#q!v5Y_edMmGNq%cc~|E- zZiM^4_8-?eAR!WMGL}9ZCbU6s%IwQLJc6i(PYgn$o^fn^TOMt#E~R$3ks3rV>aIT%Z(%c zI_C{Sj#*QtVFn$`&0MZGO5@s}luh8pZSX<1&b157y5lE01Z*5&FwVfE>k|$uLvTf8 z1){m*e17;mD~vjSeMv{Z47Z8eI*yX(?l|FAw1cy#v~Edzc&1hys@f@+K}u?|n!4Mt zv~F(=laWm3J-JKO=Te_k=IIFm-={Yvg#7wNy~13$`cp5VU%No@K>Y9J|K;RI`7jwx z=k%OR-`xLnsvhEiKc-;}@%yUFw{bHPbDk|t>St9^YPsB)e5!onC>kj-uJ11Op07dY z4;g8i+~+bdosn>4?MQjKu?wFR`!n%2Z4w;S>5yBmG{Xc0#ag}IPcK;s9b_yaLRz3=nNXYM8w%R+D7bU)A(*k} z5TXK%B$Re#9$?RJx@UojAx)ck6s9eHn z;!{Z2jm5@QzU_K8U#Y0>^r*H^;S7|2>mGW#)Zd_M+jPNk56}|LKt@bEp4~{&ttEB6 zPA;2aT(@PMaygakDwM7IuA3U0-b}j0cI|$y2mM;w^?I~1lU&E*xwi$_>KP#GipwGr z;C;&#({HsNfP7!o+ohEn&z8RUV*7Cyb3Br4p7CZSmR;N*$b{+-av?NI%(?!F@w-st zoQ-g~?$~YK>5LKUh#O0{KX{VqO2--CP0Ev;ub*YTVVKp;LO44ti~GOY`|fxu+c4nh zR8E9WB}zsiduC=eBwIN4EF&ROL`F_26-9CEl~A_q86_$EO}31zG9p4&zUxuvsNUZ9 z?T>H#zTfxt*U5R#{oMDp?rUF~0#6^C3qYxT(n*;ylPhCNH%w83!(x=^8~qZS2SnrP z&2x~TS+Cic$q>>P?u%Ieu>Skj3=@Hh+X)n!3YAN#c9jPL%03!iPUQ%jl&BUwRvffX z68w}WUt}w844Vj;)Ydh-W|%!_EOXrNhR01ifqrk9cbZnC;T^AnwOEw2XS=nOP3Ef{ zmiH|u#JaQ4J%9bAhQa@Mm00`LJsb4Mx8}3Uhh;s48@$@WuwGJ1p0sk?Bg0R7Ao%bG zpMR_8Cc|2i)v6;r_Aj!Wksf!*9?6LsarwbJvkOVKSf9qQck5o|#~RdG8%`>F9*aMt z95$v2?J%u%A^+bo?uh)dAfIC9iP!!D`|g}Ld-g*@2qlt*>61m~q24hGE=np;LG=(% zXa%%nr$dzAOqi_hq`&Yu=+n%BjP&YHGZ$8x&%`(xo8mT{ya-(cKJXi8=DyH;6ob?| z`$4r0l5#Adq@O@~j{MUm5;Br4B%9H8kgb1<{!4zxUs0nE_rFkVS9z}X4l2+_rkdKA8Z@(z zjOe866h~(Urf7e%#Qq-y)+J~%fz9CRFVMfTE-Y2!SXR2CnTQ0n;O+#!b3rOd-?`DV zim+Fu?dbWr#v@c|#h-+yy}$)kb`9}C2DitXCqRbU8$KiyWb>c|TejGI7rH5=$$5#= z9_0M+R-Yv@4RuDI2~9b(a6hf%?qe%3o9=>|ttayM?p(&HA3Y|B*Y);e)jL^eGIg3e z7-y)?vkry2xPCul*Fn6YwS4z!rrnxCo9yEQwtPS;OuoQaBhBojd&{@7BFM~x{8$2N z*jW{WxvS}s@@C=PCPEjNKsL&Yr$F+qK!x5dqz!Nvs5CgixP8a`PFtetRY zr@in}o-+~{*hbxJ?{{~f{4rN@>*o;GI&%beZ|s}fXP>cZBA92Zg}J6ox!e7e=!W?s z1KauG)K@SWJF-}tv!|E`@=frFf*K8}*R0OLcF5)Qo`Gbd@@@ZcJLb`Ll8j2l zyE#a~STq@n0G`S_PeWJaFel$b)AFX?`ew-`^4M{mw8=`-LZ~I+C+BoBEo(BW;#r?A^uN^2mlDnQ8OB z)uI`73f$Q4!DR}C}@R85mS=bd}c5V(znenN*w!vtSyoJ3U00sk|W{eNRLuv zRtbC3_RZBVc_8xQB;}(>!OQiyc}lJe=`$4xUvGHmt$e^`vR6^LRb(@@YzNHrIDSY3 z;!vJq&;W1{60F~d!~UL;Klg?G9rlc}$NIFAqC8pf7szXyIA{>_P)wD96&H>0W0SX? z2|`LU;4sAc=R#)B4=y3s8Yw0m=T^A07)hrv?GM?hLau0B0eXD&n*B`Y7FKeYb@oZ@ z1~|?6mLSrf-0p=GEM&qh{oK}ogT~O|sRK+a_C~srTK1p0cBcp8qYltR;5st0y6(aR zgpWe;bwIcyNYvFM!~X%|y=+WIEv+PBb-GE5!ChVt=Fj-87y9q^A<3rLP(59=<=(=d(R_mM6av|V>&y2ft%|f9K?9W=Exu-pEaJ zK$@gF;2wt^=u4E4b>neF<;K)~#NpO<`oZmIL7J*zyBCpOb4Zd9KZFcL-ni4-jw0!% zrNS3qAUee^9AIr<>b+C8tfa<)X*nJBSSY{M1~ktC9WLM|y>$5vhFKUo3MMtX=F z#$-Z(B;-H_B>meUWl(g%E!Wd(*i{9wZ-rGH$=C@6Nfc1>d;q5d%q&ZYqO~+xMtr4k;u~ z^PP`6V6DNWT-ZzRai=*;Y2x`03d15c$OmyQ3I)&XL~NMWL9&gXr=c_SSPg) z>+BCTI7_?J=)wuayl=!$YVdbv!9sfwFHJ4C3Gm^n|%|`C<@j& zd&=_Xhca7`oFaNEx|c7H9*cwyFXAG?jH&AbWJ!SJuI0^^5$dVF%d*Dz zsISA9zwQ^kru}u1_mzR?@ua^l=Jdmb9v-t=l@xwCyj~rVf`LfB(A0*rvmcnnBSCHI z+gbKSjutW_npE=Jhg&a@w=iu(EaM8H2FYy@74iq)?4~#7Z(!D=nHUVuJ=uedIw^oe zM8#cIFq~m0GV`Iq6)unpD5EoeJ)bK{J7hk{Y(T45aRbEt!Tqt0YMrK6x113_3h9Us zf$BE*TQA%*da`jK>Zb%P%xMzR_Edw4>sx9{zrG>Wv=^0w+EzoSVQ3{oup z+Th!gWf*mr(|9zCEBPU^6OU+~`kFu?vE5h^{XEiqkQ_2693*4LuwCnSu?7sSI`5}F zq2cp0kZRi=I)Lmw@OEX-?JSWy*` zIJVkACGTkzv4#;)VT8o9Ca1dK%7E5N&NtHbZtDWbZ^725aM1%Rx+A>>-5`ej5Hrdx2PQ)nw% zEU5|=Ue*c3np5pTd`o8hQKz~1Qo`lgD2AdYaY;8v5c5csw4G{zKTn%CB(&uiG<9-L zTFsUDuKS+0L~v&O7H(33RB&h%YVSm@P0&iT3qm@C=jO^*r08J+K_ST)s~65UT2OodC>YW=Ugg$oVpp=i+HD0edR(N7AaNMxMyRD;wU1<2mZ3KVJ(_jX|n2iaQzBZ@R% z7v@TfS?oFT4vC1;tIjq>AvN2f;4VHRrMws->w|J{O6#vP`*4(xp1=w$>Rsnq@9csL zL9d{TAEA5dm!8z}=SItv;!3bPJDUy>xEly2hYaot3FFhxSp*H3$&DbKxX03euUj27 zT47LfScZfsZkuDr_XIIPN#NUO8+Y4MSH^*li%$}W+w3}>B^hEJ*1pgjMRIHUbs=Z- zvXev*lB~vnWP4t_EzhvmZPfSUNrW zbQ2>5a)m>73+rD0GaX|inPjw-FHnDMJ5`*7vQC{!?Q>|WwZXz;59nd_GZcx6( z6_3?MBiXDKtwakqpo(8%v~(fNtltT_@kR^C2^?`VBA5j5J$cHgp>kt;dlM zPK)IS$u7kAfT<~wcQuLCvYQ;Is$x5*t!{iU9Sa0y@Tv~~xMjmj`v$jRgTBHC-bBH-O9hIQFZoq6PY z?x=S_v=ST5WgJCKlg>-Ae70~F!VU)4t zh7Dva51`>S+b!)N+kL&L5J=7vqj!390;epD+PnU>{C%eNZP2TZjvcF){OGP7)z&NA zvS94-v{6OAIvK>*$JAL0m$?}ff8VjWds_=*2h*6gAU2i{8JDok^K4M+4(J5mq3okl zqID8&%TJ}#i_{ew@-=_+P%TD8h1hFpX%Af`l5S}7sO|;0HUsqY*t));^!_>PiG)pM;Bn3by;1I*-?@EmgH=d7zHD9QPKR;9 z`t7xIh(*9UsljyooY6Fv9fV1s1GK%{SYUCrXZe%=<=W-VbRUrP6T11A-9d~=@um_~ zBbwPnM*tMe?AGxgT3ZC5kD`3d(<3_zRVRAe&g)wq=eHT4|!Ew8J7^H4&{5 zFig}pf*=u$-En?1={gLJqul1BI|oQeIneiSigs+>sbMZh)BQ#bvq|tNw3X{hA4T%) zmcWy8yKMid79bwFGI=fWvCN8R&`AI7$4J|x^v}@JGr*TR2WgS~g*poz7PsochN$mw zd_1(|PmisACQb(9*zaTpG5YzRv+PI0;U^V2FCzwf?lwQ_2Q>Pp@4Fx~dv{pm;kETS zs*fmKKWtbNl6XrmW$6^g_wyo>3Tg()$P|c^(p&(Vc?}E{U!W+_w2Vf)RZGxx-KJ>_ zlpcoFVuyo6A^4gpJ?D#_?G)0VH*I@sJ(fB1I59Tz1>jAd}?pOMx^O0{hY0dq-vsMmV-qCR+~Z(LmB3`s3qJbRp(o)zV#Ap})7KtD>Lq8jLng=em+td! zWp8Y*IBT{Dd_==gH;b{&XzDO7lV^iZ{Mld4RO%1=CMBWv*&!w4;&)TbW22dH81Mq% z*VP}8Uj)Qaa#^Z>u_lAgnZ@A7y9z@aH;>MD3wJWDZ9U9DkTkaAIYRV zR`?!rJYUX~PXxvv4#p#CySI+F$96Hco0AQYvrxnZ7(ScOY~gt#A9;xB@EbaCWw=+! zR6@Eh1JWZ?_ZXGg;7aaA`}_CkXBf*DX&<=w?>!NhNpcl+blbj>TYGQadRokser)^A zi#Nf~QxXMOltSv_^=RPTi*}g+gnctWZvu*qK+N(Rw<*pt-a7?ZwMy7|-=_|fH zOi1edQ0)ci)O}dQttcf$x>>3{Y`H!I6aA9rW&$hyEDS~d!f@)9aQ5w1^Tz#nTco|P zrT%e_*4j`dcDDO?KaN&aQx?0dTe``25?<@*U)hP~dSm9lCyzOKYAbF4h(_!o2TFSN0M;~SF#Rsb^a56OW;LlYrZ9Aj1j@wSAX371p z`R2}kR@A+6qh!wJ<$SnBPh zA#9y>OFP=<8pl?aR)ZnvOgJs#O;xZm}o2~Fn+IgqAcbuFp zW(?Mg@cv8VmA!F|su z^=&Genu(tq_cqbm`MR+A16EnDate~Zv?B$=Bh@FI@Cgznc=aPm$#@5qDJ3raPE1&O_k}agMfo4%7%BI%;6ACi?8)`T~@O1_xWGh_S=d4R$(c z@#gz^5+&H;_&DWfGH3&q&r@Ly?n61v$rXoKOPm{7qbQC(A9*|Bd2#pQswCpONp$6~Zd&fv-s zi?@PhbEOj=Zp=Yi35s&*IYpQ^<~wq`)}tp>w5h740>{UuCbVc5UWh*Vs|#`>Z8Y%Q zPgDHFM;$=t1B;+5lFTa{4P;NW#Co*CY$Q#<97 z%CSC+@6?koH1|bH23jmOXxS_7c=#Hl%-wk*@ttw927X*K8|hGKWbldOX?~8@X~l%Z z9LcJ|`TEPPof9h34+bwe>7MW2)L)aTV(f!41A zxT@kCETV4~DViAFNzh{A)>d;w_vxtLr^upjTDs52<)#JiG~mc+@O2drUq^zF zCle6bA(VGMWt?b#msT4G{x$}sXc3oVjX$kn!D@EJ`%v^;$#8C!$Anu?CwV1HrdHmE z1*mm-vXh~D))?)`LVs6XiL;)i{KO_|wiKI$BDGSiL2@Gtf1tK~ZU~cJ^5%pd>oo5p zY+TRZkOc90d{A=3zIa^~QnobcRwACx#ct7Ak#$YK(D)exnx3^Q$W{3)tM;9g{M&w~ zIQ`P%SR3z&K1A=r2MZWNTw`3sE|59h+h!^|hjID6d|d_O*U8dp4dK-EOl=TfP=8h~C%jg(PP!R+dBA~5B+-Shu9i`*RTCb|@huW0~vys{MZdELg zrv0oWPo3#WS~vTbzvt(i7*>|BWL;!tS9inLh1N0=HIEU^Ia0q$F6JEX53i>T2kF$X zk8`{qXc#4>s*xTK?8|%QJIwdU(Z1zS41J)iT1!%DWlp2j9VN01txw@QyY(&YMq>3j zZCKT@9}AIjMQJDAjFbxVyHx zAX^%JVQ|K-EN@Kc6EM0ppL%e$$)Ho2ZELuj%%L|qTI5`F7RhOND}I?8sW7+fE=^Z$ zMY*!{>v#5LrUEU6;LkH4#F2Vf*1=}Stp%VFAeK%Jb zVi;i&0VdZX!_ zY{k^@ES088GQue$@0yWkG?V%>Me9O;rPJw=5xK8+z3EHPQdPt!=e)AAY6-0ti406+ zTxj$OFHsE&PS!+|spehktTbE!CFeAi!WXVXj|%XdHXxFW+HJA~b*~uCv_ur1jc&4% zo(>~Vv#S-HEt=9cBFRW!C)$3_Sg2>QdoHgm>Xua!nNHq*_darywkKyBY-*&pwL1%S z>L)g@Tz=^yn7%NdboH$36Q#ktS1Tdrb(oV)WT{GU$Bo`|-h&8{(Cv?|8qBws@a?5$ zku@zwP3;Qc<4YW@Ig`K|aQE^7xaGL`=dHXIZk8Mym^RGV;rn)9_X^+8;OXxY2MCY|)Hwu$3eHdUxs~_a6~TVhUWRpr3p; zVL@B}%84Wi&BOX(my_ScOZ;U%7)Ebmub{h9LOCA4OV8+>Z5XRs0S|MwmNF;Lj>s$v z<11!KZ_Yz>J5Pplny>lI)I@EHcaq~6nE0&>2kWvJdiGA&Pxitm1l20C?gA^03?TL{&?*CVcVo4uRO3X7^u^F(-_KIP4z0~(r{Eet!4 z{%q-1Z~IEmo+{jGOu*k&`CvY3=E>wWz8qW&YNUELM_f8Xt=%%`Y*Kw_;ZQEyA>G^M zoEzL-iX$zrgnW%N6+dXT6&i7p29nIanrjLoqi*xWm0ae;I$74`c?+?vbYVA@Sw?kQ zDCHVn?xroWt;tLFtRC(6Oz9bHh@Bn^`s&lsP*Rw7zO*RSEp_;IQupRbrn%|lXkYA1 z(+pkA(0OR1(!`F+qx`zEVPb{qEF?SektG7 zVPa*I;cYjfowq+_z2LlS@(z_wUfwE;gU^a~op`nzeJ;LqfR)es2w&k@H09utR1{6M z$SJg!A>?wavRdtPLq?5IXij125X^4BfO_^-{KukVcMNBr! zuw9Z!MwZ%#i^eiWRe@iJu(Xjhx?v(^%L^YQqMhneMqP&HZEa-2<|JA@jOu-BZ93eN zF-%-0+G7}z&&d)d<%=ux$L@T)nGt%;lT^XUbO8J}r&G?be!ja|l*+BG z;^Vm%FeWR8@EPtFi*7SCxTGidWRDpw@Artm*D??>BM~GZo@)zi-;DGxpV)A_I?o18 zE;%gTV67IGZ>L+j!#(SM~G1Bn;}$mtwk;xi+iJp0JM!vlBcYV|lRt^~q>Yp;^%Eu=PW? zrJAF&N-gHqMbE49Kc@7tKsfV>f+?p>w4zheJFO0IL$@13O>!M#ys}|4G>p=6bVI&s zCUG^FC}QI!8PO+Nuoa#&DJHqCO2S2wfk~-BrYDSr675FC#H+MEE3zh_SjuM7?BDiR zB^{o5O68fUAe>=~4cFe}UHvq0&gGd4QguG}@dFqf#SIoMmSt4O&oi?41>HLBs^Y8G z5ofT1PutgIBB^vkxVcjr%-@f0HgMe@Pt9*Xew?m+%}#f9+S8Cc)SM9Gex2X`?eI+C%m`*(9Z>>+gQzdZ6D&~e$-#6D%_&c%`kX>FRM$DM>TQ27{Mg$?Q6 z@RFD+rBDQCZG|=ks_1J{N#?kqx6pUa^_T48VBNr=6yAS7n4zuE&b4lXV zHsSi%Ui7#`n>$+s&B_+)3JFL(rx?&LSeLZzMfEsU>r%dm7PfsjxFhqm#tE)Yn?&Fp zE>;R**B!4rNP@qSIN|i5BiTW0c0_VXkViSgA^N`zl%O*2%tc$NZNA zCT}jxPq#SgIMNX9)lgKC_pKrq5RXPfA8AQZiR3OT6ZJpHLTSWvlA}t-en0qCnQqU- zy`=3y>z+b;&~qJTXiR*Z>J|E=l57(tFXpFyS{&7%oCaeYjql7uazbva&a?ICE*AH| zTME-J!gvN4z|M?uZbK}vyi~VzH;Cw{jI;G!MbQ*>n5Q;9qxm4&f7~enb5!Bw-o6NL zdWNY0AMV^|AB6BZ)y^=qO~HX4~N*E`#x? z`;N8Q(KD&nT4s=LLg1ykDtU1;S3@uN=7-qD8Ub|L;FCJ1ES^&yx8)##4-?AT zThTcG6ePgZL7G?RM)%+?K0Fe^a>F5M0-8@bcDPNAqI5J0 zIq*Ij^C>oMsn*UBiS2q93N}edV{@~1SddC3Ed-5k(>%e6$1}{olxKJ}fx4L$jsB~W zi6jhlE9;uc9^EB~jkIrUH2!o;huhSt;r=ohvuB6z+EH#BPVp5vKum*-&3^i0;uR;ZfBV*~knmuiV9C@CEYM`xeyPmb93jhp$8l1!}l6r6dX{B0ZXCM{sz z`{|MAkaL$mLP^6gOHpKm*TG@Ls~weBM86~8Rk{k8pEeJ=iyH?-e3O(l^R00~yv+Dl zu{AlpN+FxYEVy2}3NFqFi&yD+I3-n|A8UJD$Q;dUfK88!spVR(wV8e)q?cr;efbD< zS5O-|$k&M20j{-mk}(%DZ#hl8R*U{CeQw%w8&}4r>F8$Oh7Tpuf_Gd=3h9MLXRNwC zBB!&C85x%i@#d`u=zN1AB{#ToacHOS5QRU-W_wL)TXAl}AWz`x$UwJRv5uY!dUyad zcgBeQ(w}bD={%Xj*HJvjq7SI_S9H$wY@8;gYC3j+FaEXgfk5g?sLVNd{&mX8!%_NH z;pp^feSEg(kc`gawfvS+W4dw97uo5HuGj{hR!_^f4S^)ZnAe!LaHuM~vWivE3(){z z(fc36iQIGw95uT}t0P1a3{V{Fg$SE1(lEriq}A}e%6Ukhp|Bj=SmZ$}UGlaz{KYa% z{y4+eoiJ4=Q6Zb1C!LZobbEhQ%lXKJF4lp&o(9llpeoSR__+Q9Ql2pvb_$dk`)PlW)+K+F1bgKH;LJA5_NK%f3|diKux_1-eO}tmw2PVeFo@ak9GR zT6BHy$aHaZ6CcR~W?9p>q$!)Xrn_~e%M)lTGt_Ht<#)c%VZ&9$By%GUNenHVd`2Fz zNwSy3t}<$q%$KJ&1<6X(p}gvx1+|?YeHp(|E)mQ8hCr}==}~uyj7p&foa16+`Fxdg z4&#v0!aBr(Is`Fq`o1xhLN(H71|IrbPB9Z#S^eO%kEz5-Ed3IA|G$HUUq#lX#^Vs- zzm0mbE-6Cz^=Lme(|qgjs81@LeruAz_JP-Ai%5F1IFYMAW8wJ>u2Y8Jv5#W_nK|Qd zg5o9t?B7;S)s6MeSB(_=iynH&SC)?6S^FBN4?9>UZiu)80@bgQf4M1G${UL>Y*Z!e zlwTI0Lc$x)On{0AD^p1>himKF*;dya-3D&Mm|QO6mZ?FSQ4trvKttUHu;tU(1(-gQ|dfX{Xrjv<4ky&GH3sb+=fJD-yW@{@=Bp_`fJP zhJ>bgz}oRwnM4~F&s4JNB|f))JMd6%9G&2IS}@fFght%EX!P?wGZ95(Mz0vNMlyXo zbHv4Et>Ei=ElL*R!B#(9MHqDKHJupYSLN#v=oXy5P7so9L4fGQ0izJ&QmY?Q5xVne zNk2+Jf-Im;in#dyQPi0Rkrt~ojrlnav8f>2>qN-GXw+JS2-9T*)pHB9d%hn#RtI2O zs!w_KS0>pDOv0Wju|`PzK;<>J|IQ>tDq2PT|1lEHR9Fq`iHNUjWdmg3?gI~QaT@fC z_>R3y5+H*uvBfL|e1H49E?gch;ZKc-ylDCc0P?`tGjRWRlyZZ7%nc2B@C%Jo1GQZL z$14?CT!aaJNOB?M7s9gv4Co6L)DU^m4|w0^O^yB3cO>B|fn8{(9S{7xQ`$J#DYZ^r zC~+g#Ihjg?-{6JLe&>hsjqpPeuaEbL*k1i$S_dbx*?3W$z&5xOd2vs9AB&w7cAc91wY)_Xmsz#pFv0i1gK42FE8;* z;6DSvKfzb_iXcj8wz2o6MLLbVNvc$J{^g)d{ABR-A@0CK#7oNdCcGz@JKmZ=Y%Qz~ zph?VXJTn-@TwL{ze^(DcP-Ys#&u1uy0Ji<2^sA-X_v7j6!v4$z_Y+q8rd;3- zfi&B4rjR0-a2nHIfZTc$*$M(Jq#A$(PcNPA7=oUYqfbgkiAemuln=K9C_zJz^>X&R zpkE5eNOU7Wo`kd?u)k|=Awuf==1k3Cv)5il{tS84MqpgwM}va8gkR!tfU_;`BwJz# zI6I5ObWe?UI@J`fhLP6JqU#U9x)f=2jc^PvSw#MBB2oo8I%rZmPr0_`CJ{u0MPV*Y z!G8#hi-^E5z^vc<^Om`Guum*cC#1Q%D(zeQrgsuvP1&H`055-ESblah|E#;;b$KsY z#tqe*3g|kMG#@UA9X<8SS}00j9jA4Y4~Yaot&3behxmO61oVOz05p5Be2K^n2og;r zHXsw4hT0yV8sCoX?ij+05S<~oCuDFdTd?|F{eD<}YMi@Q1eK%5je`Ljgp>)8{)U)L zuktGC*~dczuL8U0_)Le?*S`K1M2SA{#n$IY$ORzmV&C>h6$bMD40dJLQhue4PG)tV zeAOt4+&zJUHX3=ypRE~=UiZ9k~nN`{i-X`WaaNI49&z5I+ zn0svzUyyb@oI@_(|5E;P16zebQVE{w0%D4+(FTC1jdaHCD~v-tfaKlIdixQC0NmT_ z09hL|k6%CTRbH?GG1TZpaqZif8js+nc)BR+M9;Yu$X@?-N7Rq|R|r@qQRrSupFtA z1D8>9QSM&dw`+iY4;0)?@`{;woQLF(o(!h1NvTyH>12)_X>m?{phx^6g(lE>=&0qJ z??1#DlPPQWNSu3j6zTD3>{rM16E@+Znef439h@UInyy0Ef)hhWA7`?1VM&_QP!D2|rS} z>ABVWmqw-z!qwcY{CZAGE;by;_OCr7762>ZzC;rAD<=N5gyb2TKy2)Lwdzv z*_iPGQH;}r#+#MhGNN&t&(1g&QrsdCy{S2f;C%)TO$6mE^@wSU&$DEQ zv?D#j1XOb}cV&k%9jp0Rgx^~sy)iWkb__BZxizc-c%maVT2~aXG z{dKY8X(=r&KY`)NH!OVVPRQu1me$A5C3qAG*DMAs6_?nLOm!bUouZZ^7XKK5uTVV6 zZZ5)aCIMqtO%4+%hm67?R%@VoQ=^fzJHxE)ZA1olax}Jt$YsYDK#JxUXn3+ZlTmzaIc52^8si*pp}vW@_UwL!3K}1`H}~_B`@kpom1OBpgMuTOenI?pn#^d)|_(q4tEmL6dLtP)8@E^-9=tjC*O0OUP86- z#TLC@s581-Ziapoe^EE9e_Thney}zA?UZvpfr`PebOCmBKO^=N@uWn__PY=K$Kmlq zyb*`~@bUk@I)Q?J5b_At{%?l6I%-wbVDg!4S+}z;V2v(+M=>DmMaU?GZ69x$9g_8u zl>v#d@R;%#(JWn+F+@84GviZ=w=`@BiiT%qY_2_AT~C*Ybzb!#XeV-d*!S z{w!mO^6T4&-y0VQzWk1r&n+Cwe#55t>+9RR;f7;-V-)zyTEECnI1X*J7vDUEeVt#Z zYy(&|m!8OiHvON!f_2KBK}ED1E(+iA3+em=2&8s`S~^ck_lt4y_Z=~1R+8qO?0Q!z zEKE8LTN>IePH>C$8Q3<(UZIT{uTUd8_aYB;ernw`Nhxl zd#Zw0{Kw{PlgiIF9XMzpA=>n#xgxs)XI>~fcI^0{p@9ZLLtosio8pto=7|{riGSee zA7O`c0?RZ_sl(|HPp%G+7w-APhyTGbvIfT=cLKEYlPiyi%5NXapRSq>;x3|>e*ArT zDE#V0PRG#S2>-{Yh*T_V5078U-oBBby8rem;^Y4_S1-q{3L|lKDpjHeOn7@LIKXVu zx_FQM5u(@Oih(e?(7!;4xa(g&{DUXuCt@wPC2=DuK1jgpDNycr)hI^n|1*Xzg$UM2 zvm-6VpFRHPt2>C1I+sWxF$G#2h%qvn_U-vc%U8zo&6!mQwl;x=#FR-G@6#uyKlz2_ zaad5u()6`1{~@^kW?udK?{srvW65$ee1+*gGpJ;D!}vy5(9Aj0xVGB>sS%_KYRTD!PTogR+*jo7mo%J;6HsZ9S54Q z*?;lSpMjI?!0pN4;y;rVB&55+*U_=ANNLUAMG!ha2>^o3_$lB(V6ET(0=EUcUUuu= zvi`zw|0Dz;7Rd1XmHzgNe{eUio;euPW*2U0l_V7Pci=W2fqR*O_ZIWd=E>jI|9;xc zWdM9<*$c}*yI^Ih5Vfd){rcZu{5wdM&w}8wTiF%C{7>)y`Bzfl6Cde|qx~V+^lt>w z$pSsTp%6Eg9qsT?Z9ilx(*Q};UK)A>YqKHrwF%e zN^q0;Ph9tp3`Bbij;^jEOWqlAmFol!{l|SHV8`7Dp4?)Q;P>C^{_5ku13V>LX6J#r`lm$>BL7IZu@I@& zmS^|*Gd`0w#lxXf-oOO5Kf{;=XtGY;jQ9QAr?mlYY z`3)U8!&9ck-Mthq(^pq4gRZDR5H?OpKgAbtw4E#(xu^q&dypUCi6 zm*0P&@PF&-<+Eg~?n$X8fo*>S&JP?5kWzHToq3VC>`+;2k_vj6_#jCLElvbGj zN41y8wv_DPGnbWp_-DRCSyMVdhQ*u6BR`z#U%-P~58`YOb>jyjxc>cvE_lst=!A!V zhtl7`xYrAW>n79%iGSI`k6#5Nk(*<6;=kWSBh_lKWkF#35AliBxBe0c{4Z)xh2#~R z4L6GZU8)jSDUX9w_}&s#DYCz;=q^_wYh4-O3G1POsis))S6O4@Vze=b}oCSrESXJx0s3;OI5g z;{Lxq=#Q^$V<2hXlyAjT=Uwgv8{C+qdtEU$hV(0{sliDAiqVOOfU0zir_Q~2yh;RGl1I`ZO&K*O|!o&bM0np_E8{GYEUZz-$ z{e6`^a3BdLaqs`w58+)YNUlrnqpyVj|9!!q{?d2|q}uv>NB;2fOeCuW>pSw_DEWrk z|Am`p7@iDUw~nM-;pibP*!}+%2Z6{jk}Os$Q@iyiED%Vs%@V+CXKZx-zeO{Gu-JTH zkW!;v>-WjV(o80}&#fmA)ISnSrXBpGGcRuF&t!Bt6T(i9l{YH +Euler Earn invariant suite +
+ +The Invariant Testing Suite serves as middleware between the tooling and the Protocol. The system’s setup can be split into the following components: + +- **Tooling**: Tool or set of tools used to test the system, targeting the suite middleware in order to conduct fuzzing campaigns and check properties. In this case, the tooling used is Echidna, a property-based testing tool for Ethereum smart contracts. +- **Test Suite**: Middleware that connects the tooling with the protocol, which orchestrates all interactions with it, including the actors, handlers, and properties. It is responsible for setting up the environment, running the tests, and reporting the results. +- **Local Protocol Deployment**: Local testing deployment of the protocol, whose setup is primarily based on the existing deployment scripts of Euler Earn. The Test Suite contracts are designed to setup and interact with this deployment of the protocol. + +## Inheritance Hierarchy + +The Test Suite centers around the main `Tester` contract, which inherits from several other contracts, each designated with a specific function within the system. The inheritance hierarchy appears as follows: +

+ +Euler Earn invariant suite inheritance +
+ +This illustrates the inheritance graph for the suite. + +# Test Suite Architecture + +The Test Suite follows a modular architecture designed to address the different types of properties and upgrade needs for complex protocols like Euler Earn. It is designed to be flexible and easy to integrate with new features, allowing for the reuse of existing components and the addition of new ones. The Test Suite is composed of the following components: + +- **Base**: Base contracts of the Test Suite, which include the Storage contract, the Setup contract, and a few more. The Storage contract is responsible for storing protocol deployment addresses and extra variables, while the Setup contract is responsible for setting up the environment for the tests. +- **Actors**: Actors of the Test Suite, which represent the different entities interacting with the protocol. Each actor is a proxy-like contract that forwards specific actions from the handlers to the protocol. +- **Handlers**: Contracts that contain external-facing functions for tooling to execute user actions via actors. They are designed to be modular and extensible, allowing for the addition of new functions and features (eg. liquid eModes). +- **Hooks**: Responsible for caching protocol and user values before and after calls, as well as executing global postconditions. They are designed to be modular and extensible, allowing for the incorporation of additional postconditions and value caching as needed. +- **Properties**: Contracts that define the specifications and implement the required checks to ensure properties hold in the system. + +## Base + +The base contracts of the Test Suite are responsible for setting up the environment for the tests, storing the protocol deployment addresses and extra variables and helper functions for handlers and hooks. + +It is composed by the following smart contracts: + +- **BaseHandler**: Base contract that contains helper functions for the handlers such as random selectors for assets, Atokens, DebtTokens, eMode categories and priceAggregators. It is inherited by all handler contracts. + +- **BaseHooks**: Base contract where common logic for the hooks is implemented. In the case of this suite, no helper functions are implemented in this contract it is just used to agregate parent contracts: ProtocolAssertions and SpecAggregator. + +- **BaseStorage**: Storage contract that stores protocol deployment addresses and extra variables. This contract is the root of the inheritance chain, serving as the main parent contract. + +- **BaseTest**: Test temmplate contract that contains general protocol helper functions and the `setup` actor selector modifier implementation. It is inherited by all test contracts. + +- **ProtocolAssertions**: Helper contract for protocol specific assertions which are reused along the codebase. + +## Actors + +Actors are smart contract entities that interact with the protocol as showcased in the diagram. These contracts act as a proxy between the handlers and the protocol, forwarding actions to the protocols acting as the "real" users. The tooling for this suite is configured to randomly use three callers `USER1`, `USER2` and `USER3` to interact with the handlers. The `setup` modifier in the `BaseTest` contract is used on every user handler to select the actor to be used in the proxied call to the protocol based on the caller of the handler function. + +Example: `setup` Modifier in Action + +```solidity +function redeem(uint256 amount, uint8 i) external setup { + /// setup modifier selects the actor to be used in the proxied call + /// based on the caller of this handler function + + bool success; /// success flag and returnData for the proxied call are declared at the beginning of the function + bytes memory returnData; + + ... + + address target = address(eulerEulerEarnVault); + + _before(); + + /// actor.proxy is used to call the protocol, targetting the protocol with the required calldata + (success, returnData) = actor.proxy( + target, + abi.encodeWithSelector( + IERC4626.redeem.selector, + shares, + receiver, + address(actor) + ) + ); + + if (success) { /// success flag is checked to ensure the call was successful in order to make further checks + _after(); + ... + } +} +``` + +The Actor contract is located under `utils/`. + +## Handlers + +The Handlers contain the main functions exposed to the tooling, allowing it to execute actions through actors. They have been divided in three different categories: `user`, `permissioned` and `simulators`. Each of them implementing different actions and functionalities of the protocol, from user actions to price movement simmulators. + +- **Modules**: Handlers that contain functions to execute user actions or permissioned actions in the protocol. These actions are executed by the actors or the Tester contract itself and are used to test the protocol's behavior under different scenarios. All the exposed user functions on these handler category use the `setup` mmodifier showed above. Includes `ERC20Handler`, `ERC4626Handler`, `EulerEarnVaultModuleHandler`, `FeeModuleHandler`, `StrategyModuleHandler` and `WithdrawalQueueModuleHandler`. + +- **Simulators**: Handlers that contain functions which simulate real world external changes like donation attacks, asset price movements or flashloans. Includes `DonationAttackHandler` and `NigativeYieldHandler`. + +## Hooks + +Hooks handle caching of protocol and user values and enforce postconditions across the suite. They allow for modular expansion to add new postconditions, or additional value caching as needed. + +- `DefaultBeforeAfterHooks`: Abstract contract that contains the `DefaultVars` struct and custom setter functions, which is essential for caching protocol and user values before and after function calls. It also implements the global postconditions (GPOST) to be invoked in the `HookAggregator::_checkPostConditions` function. +- `HookAggregator`: This contract aggregates various hooks (only the default one in this case) and invokes the `_checkPostConditions` function to execute the global postconditions. + +Values are cached before and after nearly every handler call using `_after` and `_before` functions. The `DefaultVars` struct contains the following fields: + +```solidity + // Vault Accounting + uint256 totalSupply; + uint256 totalAssets; + uint256 totalAssetsAllocatable; + uint256 totalAssetsDeposited; + uint256 totalAllocated; + // External Accounting + uint256 balance; + uint256 exchangeRate; + uint256 toGulp; + // Interest + uint256 lastHarvestTimestamp; + uint40 lastInterestUpdate; + uint40 interestSmearingEnd; + uint168 interestLeft; + uint256 interestAccrued; + // Strategies data + mapping(address => Strategy) strategies; +``` + +Example: `_checkPostConditions` function, called at the end of the `_after` hook + +```solidity +function _after() internal { + _defaultHooksAfter(); + + // POST-CONDITIONS + _checkPostConditions(); + + // RESET + targetStrategy = address(0); +} + +/// @notice Postconditions for the handlers +function _checkPostConditions() internal { + // BASE + assert_GPOST_BASE_A(); + assert_GPOST_BASE_B(); + assert_GPOST_BASE_C(); + // INTEREST + assert_GPOST_INTEREST_A(); + assert_GPOST_INTEREST_B(); + // STRATEGY + assert_GPOST_STRATEGIES_A(); + assert_GPOST_STRATEGIES_H(); +} +``` + +## Properties + +Inside this testing suite, properties are the most important component, everything else works as scaffolding, helpers and setup scripts to ensure the tooling is able to reach the most amount of edge cases possible. The properties are the actual checks that are being run, they are the ones that ensure the protocol is behaving as expected. The properties are divided in two categories: invariants and postconditions. + +- **Invariants**: Properties that should always hold true in the system. The tooling executes them in between every transaction to ensure the system is not in an invalid state. They are implemented in the `BaseInvariants` and `ERC4626Invariants` contract following the specs at `InvariantsSpec`, `ERC4626PropertiesSpec` and `NonRevertPropertiesSpec`. + +- **Postconditions**: Properties that should hold true after a specific action is executed. There are two types of postconditions: global postconditions (GPOST) and handler specific postconditions (HSPOST). + - **GPOST**: Postconditions that are executed after every handler call. They are implemented in the `HookAggregator` contract. + - **HSPOST**: Postconditions that are executed after specific handler calls, very similar to unit test assertions. They are usually implemented in the success block at the end of a handler function. diff --git a/test/enigma-dark-invariants/handlers/euler/EVCHandler.t.sol b/test/enigma-dark-invariants/handlers/euler/EVCHandler.t.sol new file mode 100644 index 0000000..d201f5a --- /dev/null +++ b/test/enigma-dark-invariants/handlers/euler/EVCHandler.t.sol @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Libraries +import {EthereumVaultConnector} from "ethereum-vault-connector/EthereumVaultConnector.sol"; + +// Testing contracts +import {Actor} from "../../utils/Actor.sol"; +import {BaseHandler, EnumerableSet} from "../../base/BaseHandler.t.sol"; + +/// @title EVCHandler +/// @notice Handler test contract for the EVC actions +abstract contract EVCHandler is BaseHandler { + using EnumerableSet for EnumerableSet.AddressSet; + + /////////////////////////////////////////////////////////////////////////////////////////////// + // STATE VARIABLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // GHOST VARAIBLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // ACTIONS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function setAccountOperator(uint8 i, uint8 j, bool authorised) external setup { + bool success; + bytes memory returnData; + + address account = _getRandomActor(i); + + address operator = _getRandomActor(j); + + _before(); + (success, returnData) = actor.proxy( + address(evc), + abi.encodeWithSelector(EthereumVaultConnector.setAccountOperator.selector, account, operator, authorised) + ); + + if (success) { + _after(); + } + } + + // COLLATERAL + + function enableCollateral(uint8 i, uint8 j) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address account = _getRandomActor(i); + + address vaultAddress = _getRandomVault(j); + + _before(); + (success, returnData) = actor.proxy( + address(evc), + abi.encodeWithSelector(EthereumVaultConnector.enableCollateral.selector, account, vaultAddress) + ); + + if (success) { + _after(); + } + } + + function disableCollateral(uint8 i, uint8 j) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address account = _getRandomActor(i); + + address vaultAddress = _getRandomVault(j); + + _before(); + (success, returnData) = actor.proxy( + address(evc), + abi.encodeWithSelector(EthereumVaultConnector.disableCollateral.selector, account, vaultAddress) + ); + + if (success) { + _after(); + } + } + + function reorderCollaterals(uint8 i, uint8 index1, uint8 index2) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address account = _getRandomActor(i); + + _before(); + (success, returnData) = actor.proxy( + address(evc), + abi.encodeWithSelector(EthereumVaultConnector.reorderCollaterals.selector, account, index1, index2) + ); + + if (success) { + _after(); + } + } + + // CONTROLLER + + function enableController(uint8 i, uint8 j) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address account = _getRandomActor(i); + + address vault = _getRandomVault(j); + + _before(); + (success, returnData) = actor.proxy( + address(evc), abi.encodeWithSelector(EthereumVaultConnector.enableController.selector, account, vault) + ); + + if (success) { + _after(); + } + } + + function disableControllerEVC(uint8 i) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address account = _getRandomActor(i); + + _before(); + (success, returnData) = actor.proxy( + address(evc), abi.encodeWithSelector(EthereumVaultConnector.disableController.selector, account) + ); + _after(); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HELPERS // + /////////////////////////////////////////////////////////////////////////////////////////////// +} diff --git a/test/enigma-dark-invariants/handlers/interfaces/IERC4626Handler.sol b/test/enigma-dark-invariants/handlers/interfaces/IERC4626Handler.sol new file mode 100644 index 0000000..6b98f2f --- /dev/null +++ b/test/enigma-dark-invariants/handlers/interfaces/IERC4626Handler.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +interface IERC4626Handler { + function withdraw(uint256 assets, uint8 i) external; + function redeem(uint256 shares, uint8 i) external; +} diff --git a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol new file mode 100644 index 0000000..12dde69 --- /dev/null +++ b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Interfaces +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; + +// Libraries +import "forge-std/console.sol"; + +// Test Contracts +import {Actor} from "../../utils/Actor.sol"; +import {TestERC20} from "../../utils/mocks/TestERC20.sol"; +import {BaseHandler} from "../../base/BaseHandler.t.sol"; + +/// @title DonationAttackHandler +/// @notice Handler test contract for a set of actions +contract DonationAttackHandler is BaseHandler { + /////////////////////////////////////////////////////////////////////////////////////////////// + // STATE VARIABLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // ACTIONS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @notice This function transfers any amount of assets to a contract in the system simulating + /// a big range of donation attacks + function donateUnderlying(uint256 amount, uint8 i) external { + TestERC20 _token = TestERC20(_getRandomBaseAsset(i)); + + address target = address(maglev); + + _token.mint(address(this), amount); + + _token.transfer(target, amount); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // OWNER ACTIONS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HELPERS // + /////////////////////////////////////////////////////////////////////////////////////////////// +} diff --git a/test/enigma-dark-invariants/handlers/simulators/PriceOracleHandler.t.sol b/test/enigma-dark-invariants/handlers/simulators/PriceOracleHandler.t.sol new file mode 100644 index 0000000..a97a875 --- /dev/null +++ b/test/enigma-dark-invariants/handlers/simulators/PriceOracleHandler.t.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {BaseHandler} from "../../base/BaseHandler.t.sol"; + +/// @title PriceOracleHandler +/// @notice Handler test contract for the PriceOracle actions +abstract contract PriceOracleHandler is BaseHandler { + /////////////////////////////////////////////////////////////////////////////////////////////// + // STATE VARIABLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // GHOST VARAIBLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // ACTIONS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @notice This function simulates changes in the interest rate model + function setPrice(uint8 i, uint256 price) external { + address baseAsset = _getRandomBaseAsset(i); + + oracle.setPrice(baseAsset, unitOfAccount, price); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HELPERS // + /////////////////////////////////////////////////////////////////////////////////////////////// +} diff --git a/test/enigma-dark-invariants/handlers/standard/ERC20Handler.t.sol b/test/enigma-dark-invariants/handlers/standard/ERC20Handler.t.sol new file mode 100644 index 0000000..a3959d5 --- /dev/null +++ b/test/enigma-dark-invariants/handlers/standard/ERC20Handler.t.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Interfaces +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +// Libraries +import "forge-std/console.sol"; + +// Test Contracts +import {Actor} from "../../utils/Actor.sol"; +import {BaseHandler} from "../../base/BaseHandler.t.sol"; + +/// @title ERC20Handler +/// @notice Handler test contract for a set of actions +abstract contract ERC20Handler is BaseHandler { + /////////////////////////////////////////////////////////////////////////////////////////////// + // STATE VARIABLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // ACTIONS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function approve(uint256 amount, uint8 i, uint8 j) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address spender = _getRandomActor(i); + + // Get one of the vaults randomly + address target = _getRandomVault(j); + + _before(); + (success, returnData) = actor.proxy(target, abi.encodeWithSelector(IERC20.approve.selector, spender, amount)); + + if (success) { + _after(); + + assert(true); + } + } + + function transfer(uint256 amount, uint8 i, uint8 j) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address to = _getRandomActor(i); + + // Get one of the vaults randomly + address target = _getRandomVault(j); + + _before(); + (success, returnData) = actor.proxy(target, abi.encodeWithSelector(IERC20.transfer.selector, to, amount)); + + if (success) { + _after(); + + assert(true); + } + } + + function transferFrom(uint256 amount, uint8 i, uint8 j, uint8 k) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address from = _getRandomActor(i); + // Get one of the three actors randomly + address to = _getRandomActor(j); + + // Get one of the vaults randomly + address target = _getRandomVault(k); + + _before(); + (success, returnData) = + actor.proxy(target, abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, amount)); + + if (success) { + _after(); + + assert(true); + } + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // OWNER ACTIONS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HELPERS // + /////////////////////////////////////////////////////////////////////////////////////////////// +} diff --git a/test/enigma-dark-invariants/handlers/standard/ERC4626Handler.t.sol b/test/enigma-dark-invariants/handlers/standard/ERC4626Handler.t.sol new file mode 100644 index 0000000..d51294d --- /dev/null +++ b/test/enigma-dark-invariants/handlers/standard/ERC4626Handler.t.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Interfaces +import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol"; +import {IERC4626} from "openzeppelin-contracts/interfaces/IERC4626.sol"; + +// Libraries +import "forge-std/console.sol"; + +// Test Contracts +import {Actor} from "../../utils/Actor.sol"; +import {BaseHandler} from "../../base/BaseHandler.t.sol"; + +/// @title ERC4626Handler +/// @notice Handler test contract for a set of actions +abstract contract ERC4626Handler is BaseHandler { + /////////////////////////////////////////////////////////////////////////////////////////////// + // STATE VARIABLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // ACTIONS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function deposit(uint256 assets, uint8 i, uint8 j) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address receiver = _getRandomActor(i); + + // Get one of the vaults randomly + address target = _getRandomVault(j); + + _before(); + (success, returnData) = actor.proxy(target, abi.encodeWithSelector(IERC4626.deposit.selector, assets, receiver)); + + if (success) { + _after(); + } + } + + function mint(uint256 shares, uint8 i, uint8 j) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address receiver = _getRandomActor(i); + + // Get one of the vaults randomly + address target = _getRandomVault(j); + + _before(); + (success, returnData) = actor.proxy(target, abi.encodeWithSelector(IERC4626.mint.selector, shares, receiver)); + + if (success) { + _after(); + } + } + + function withdraw(uint256 assets, uint8 i, uint8 j) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address receiver = _getRandomActor(i); + + // Get one of the vaults randomly + address target = _getRandomVault(j); + + _before(); + (success, returnData) = + actor.proxy(target, abi.encodeWithSelector(IERC4626.withdraw.selector, assets, receiver, address(actor))); + + if (success) { + _after(); + } + } + + function redeem(uint256 shares, uint8 i, uint8 j) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address receiver = _getRandomActor(i); + + // Get one of the vaults randomly + address target = _getRandomVault(j); + + _before(); + (success, returnData) = + actor.proxy(target, abi.encodeWithSelector(IERC4626.redeem.selector, shares, receiver, address(actor))); + + if (success) { + _after(); + } + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HELPERS // + /////////////////////////////////////////////////////////////////////////////////////////////// +} diff --git a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol new file mode 100644 index 0000000..92c7b55 --- /dev/null +++ b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Interfaces +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IMaglevBase} from "src/interfaces/IMaglevBase.sol"; + +// Libraries +import "forge-std/console.sol"; + +// Test Contracts +import {Actor} from "../../utils/Actor.sol"; +import {BaseHandler} from "../../base/BaseHandler.t.sol"; + +/// @title MaglevHandler +/// @notice Handler test contract for a set of actions +abstract contract MaglevHandler is BaseHandler { + /////////////////////////////////////////////////////////////////////////////////////////////// + // STATE VARIABLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // ACTIONS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function swap(uint256 amount0Out, uint256 amount1Out, uint8 i) external setup { + bool success; + bytes memory returnData; + + // Get one of the three actors randomly + address to = _getRandomActor(i); + + address target = address(maglev); + + _before(); + (success, returnData) = + actor.proxy(target, abi.encodeWithSelector(IMaglevBase.swap.selector, amount0Out, amount1Out, to, "")); + + if (success) { + _after(); + } + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HELPERS // + /////////////////////////////////////////////////////////////////////////////////////////////// +} diff --git a/test/enigma-dark-invariants/helpers/extended/.gitkeep b/test/enigma-dark-invariants/helpers/extended/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol b/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol new file mode 100644 index 0000000..bc7c6d0 --- /dev/null +++ b/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Libraries +import "forge-std/console.sol"; + +// Test Contracts +import {BaseHooks} from "../base/BaseHooks.t.sol"; + +// Interfaces +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IERC4626Handler} from "../handlers/interfaces/IERC4626Handler.sol"; + +/// @title Default Before After Hooks +/// @notice Helper contract for before and after hooks +/// @dev This contract is inherited by handlers +abstract contract DefaultBeforeAfterHooks is BaseHooks { + /////////////////////////////////////////////////////////////////////////////////////////////// + // STRUCTS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + struct User { + uint256 assetTSTBalance; + uint256 assetTST2Balance; + } + + struct DefaultVars { + mapping(address => User) users; + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HOOKS STORAGE // + /////////////////////////////////////////////////////////////////////////////////////////////// + + DefaultVars defaultVarsBefore; + DefaultVars defaultVarsAfter; + + /////////////////////////////////////////////////////////////////////////////////////////////// + // SETUP // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @notice Default hooks setup + function _setUpDefaultHooks() internal {} + + /// @notice Helper to initialize storage arrays of default vars + function _setUpDefaultVars(DefaultVars storage _dafaultVars) internal {} + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HOOKS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function _defaultHooksBefore() internal { + // Default values + _setVaultValues(defaultVarsBefore); + // Health & user account data + _setUserValues(defaultVarsBefore); + } + + function _defaultHooksAfter() internal { + // Default values + _setVaultValues(defaultVarsAfter); + // Health & user account data + _setUserValues(defaultVarsAfter); + } + + /*///////////////////////////////////////////////////////////////////////////////////////////// + // HELPERS // + /////////////////////////////////////////////////////////////////////////////////////////////*/ + + function _setVaultValues(DefaultVars storage _defaultVars) internal {} + + function _setUserValues(DefaultVars storage _defaultVars) internal { + for (uint256 i; i < actorAddresses.length; i++) { + _setUserValuesPerActor(_defaultVars.users[actorAddresses[i]]); + } + } + + function _setUserValuesPerActor(User storage _user) internal {} + + /////////////////////////////////////////////////////////////////////////////////////////////// + // POST CONDITIONS: BASE // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function assert_GPOST_BASE_A() internal {} +} diff --git a/test/enigma-dark-invariants/hooks/HookAggregator.t.sol b/test/enigma-dark-invariants/hooks/HookAggregator.t.sol new file mode 100644 index 0000000..2f4df46 --- /dev/null +++ b/test/enigma-dark-invariants/hooks/HookAggregator.t.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Hook Contracts +import {DefaultBeforeAfterHooks} from "./DefaultBeforeAfterHooks.t.sol"; + +/// @title HookAggregator +/// @notice Helper contract to aggregate all before / after hook contracts, inherited on each handler +abstract contract HookAggregator is DefaultBeforeAfterHooks { + /// @notice Initializer for the hooks + function _setUpHooks() internal { + _setUpDefaultHooks(); + } + + /*///////////////////////////////////////////////////////////////////////////////////////////// + // HOOKS // + /////////////////////////////////////////////////////////////////////////////////////////////*/ + + /// @notice Modular hook selector, per module + function _before() internal { + _defaultHooksBefore(); + } + + /// @notice Modular hook selector, per module + function _after() internal { + _defaultHooksAfter(); + + // POST-CONDITIONS + _checkPostConditions(); + } + + /*///////////////////////////////////////////////////////////////////////////////////////////// + // POSTCONDITION CHECKS // + /////////////////////////////////////////////////////////////////////////////////////////////*/ + + /// @notice Postconditions for the handlers + function _checkPostConditions() internal { + // Check general postconditions + _checkGeneralPostConditions(); + + // Check user postconditions + for (uint256 i; i < actorAddresses.length; i++) { + _checkUserPostConditions(actorAddresses[i]); + } + } + + function _checkGeneralPostConditions() internal { + // Check general postconditions + } + + /// @notice Postconditions for each user + function _checkUserPostConditions(address user) internal { + // Check user postconditions + } +} diff --git a/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol b/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol new file mode 100644 index 0000000..80df69f --- /dev/null +++ b/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Libraries + +// Interfaces +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +// Contracts +import {HandlerAggregator} from "../HandlerAggregator.t.sol"; + +import "forge-std/console.sol"; + +/// @title BaseInvariants +/// @notice Implements Invariants for the protocol +/// @dev Inherits HandlerAggregator to check actions in assertion testing mode +abstract contract BaseInvariants is HandlerAggregator { + /////////////////////////////////////////////////////////////////////////////////////////////// + // BASE // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function assert_INV_BASE_A() internal {} +} diff --git a/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol b/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol new file mode 100644 index 0000000..32bf19b --- /dev/null +++ b/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +/// @title InvariantsSpec +/// @notice Invariants specification for the protocol +/// @dev Contains pseudo code and description for the invariant properties in the protocol +abstract contract InvariantsSpec { + /*///////////////////////////////////////////////////////////////////////////////////////////// + // PROPERTY TYPES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// - INVARIANTS (INV): + /// - Properties that should always hold true in the system. + /// - Implemented in the /invariants folder. + + /////////////////////////////////////////////////////////////////////////////////////////////*/ + + /////////////////////////////////////////////////////////////////////////////////////////////// + // BASE // + /////////////////////////////////////////////////////////////////////////////////////////////// + + string constant INV_BASE_A = "INV_BASE_A: performanceFee should be between bounds"; +} diff --git a/test/enigma-dark-invariants/specs/NonRevertPropertiesSpec.t.sol b/test/enigma-dark-invariants/specs/NonRevertPropertiesSpec.t.sol new file mode 100644 index 0000000..71bef7a --- /dev/null +++ b/test/enigma-dark-invariants/specs/NonRevertPropertiesSpec.t.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +/// @title NonRevertPropertiesSpec +/// @notice Properties specification for the protocol +/// @dev Contains pseudo code and description for the invariant properties in the protocol +abstract contract NonRevertPropertiesSpec { + /*///////////////////////////////////////////////////////////////////////////////////////////// + // PROPERTY TYPES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// - NON REVERT (NR): + /// - Properties that assert a specific function should never revert, or only revert under + /// certain defined conditions. + + /////////////////////////////////////////////////////////////////////////////////////////////*/ + + /////////////////////////////////////////////////////////////////////////////////////////////// + // BASE // + /////////////////////////////////////////////////////////////////////////////////////////////// + + string constant NR_BASE_A = "NR_BASE_A: updateInterestAccrued should not revert"; +} diff --git a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol new file mode 100644 index 0000000..650bba3 --- /dev/null +++ b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +/// @title PostconditionsSpec +/// @notice Postcoditions specification for the protocol +/// @dev Contains pseudo code and description for the postcondition properties in the protocol +abstract contract PostconditionsSpec { + /*///////////////////////////////////////////////////////////////////////////////////////////// + // PROPERTY TYPES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// - POSTCONDITIONS: + /// - Properties that should hold true after an action is executed. + /// - Implemented in the /hooks and /handlers folders. + /// - There are two types of POSTCONDITIONS: + /// - GLOBAL POSTCONDITIONS (GPOST): + /// - Properties that should always hold true after any action is executed. + /// - Checked in the `_checkPostConditions` function within the HookAggregator contract. + /// - HANDLER-SPECIFIC POSTCONDITIONS (HSPOST): + /// - Properties that should hold true after a specific action is executed in a specific context. + /// - Implemented within each handler function, under the HANDLER-SPECIFIC POSTCONDITIONS section. + + /////////////////////////////////////////////////////////////////////////////////////////////*/ + + /////////////////////////////////////////////////////////////////////////////////////////////// + // BASE // + /////////////////////////////////////////////////////////////////////////////////////////////// + + string constant GPOST_BASE_A = "GPOST_BASE_A: lastHarvestTimestamp increases monotonically"; +} diff --git a/test/enigma-dark-invariants/utils/Actor.sol b/test/enigma-dark-invariants/utils/Actor.sol new file mode 100644 index 0000000..5b24cb8 --- /dev/null +++ b/test/enigma-dark-invariants/utils/Actor.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Interfaces +import {IERC20} from "forge-std/interfaces/IERC20.sol"; + +/// @notice Proxy contract for invariant suite actors to avoid aTester calling contracts +contract Actor { + /// @notice list of tokens to approve + address[] internal tokens; + /// @notice list of contracts to approve tokens to + address[] internal contracts; + + constructor(address[] memory _tokens, address[] memory _contracts) payable { + tokens = _tokens; + contracts = _contracts; + for (uint256 i = 0; i < tokens.length; i++) { + for (uint256 j = 0; j < contracts.length; j++) { + IERC20(tokens[i]).approve(contracts[j], type(uint256).max); + } + } + } + + /// @notice Helper function to proxy a call to a target contract, used to avoid Tester calling contracts + function proxy(address _target, bytes memory _calldata) public returns (bool success, bytes memory returnData) { + (success, returnData) = address(_target).call(_calldata); + + handleAssertionError(success, returnData); + } + + /// @notice Helper function to proxy a call and value to a target contract, used to avoid Tester calling contracts + function proxy(address _target, bytes memory _calldata, uint256 value) + public + returns (bool success, bytes memory returnData) + { + (success, returnData) = address(_target).call{value: value}(_calldata); + + handleAssertionError(success, returnData); + } + + /// @notice Checks if a call failed due to an assertion error and propagates the error if found. + /// @param success Indicates whether the call was successful. + /// @param returnData The data returned from the call. + function handleAssertionError(bool success, bytes memory returnData) internal pure { + if (!success && returnData.length == 36) { + bytes4 selector; + uint256 code; + assembly { + selector := mload(add(returnData, 0x20)) + code := mload(add(returnData, 0x24)) + } + + if (selector == bytes4(0x4e487b71) && code == 1) { + assert(false); + } + } + } + + receive() external payable {} +} diff --git a/test/enigma-dark-invariants/utils/Create2Factory.sol b/test/enigma-dark-invariants/utils/Create2Factory.sol new file mode 100644 index 0000000..1d41779 --- /dev/null +++ b/test/enigma-dark-invariants/utils/Create2Factory.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract Create2Factory { + // Fallback function to handle the creation of a new contract + fallback() external payable { + // Copy calldata into memory, excluding the first 32 bytes + assembly { + calldatacopy(0, 32, sub(calldatasize(), 32)) + + // Create the new contract with CREATE2 + let result := create2(callvalue(), 0, sub(calldatasize(), 32), calldataload(0)) + + // Check if contract creation was successful + if iszero(result) { revert(0, 0) } + + // Return the address of the newly created contract + mstore(0, result) + return(12, 20) + } + } +} + +contract FactoryDeployer { + function deployFactory() public returns (address child) { + bytes memory bytecode = + hex"604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"; + assembly { + child := create(0, add(bytecode, 0x20), mload(bytecode)) + } + } +} diff --git a/test/enigma-dark-invariants/utils/DeployPermit2.sol b/test/enigma-dark-invariants/utils/DeployPermit2.sol new file mode 100644 index 0000000..3fe83dc --- /dev/null +++ b/test/enigma-dark-invariants/utils/DeployPermit2.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +/// @notice helper to deploy permit2 from precompiled bytecode +/// @dev useful if testing externally against permit2 and want to avoid +/// recompiling entirely and requiring viaIR compilation +library DeployPermit2 { + /// @notice deploy permit2 + function deployPermit2() internal returns (address) { + bytes memory bytecode = + hex"60c0346100bb574660a052602081017f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a60408301524660608301523060808301526080825260a082019180831060018060401b038411176100a557826040525190206080526123c090816100c1823960805181611b47015260a05181611b210152f35b634e487b7160e01b600052604160045260246000fd5b600080fdfe6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000000003611b69577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a"; + + return deployFromBytecode(bytecode); + } + + /// @notice helper function to deploy bytecode + function deployFromBytecode(bytes memory bytecode) internal returns (address child) { + assembly { + child := create(0, add(bytecode, 0x20), mload(bytecode)) + } + } +} diff --git a/test/enigma-dark-invariants/utils/Pretty.sol b/test/enigma-dark-invariants/utils/Pretty.sol new file mode 100644 index 0000000..27a6ba5 --- /dev/null +++ b/test/enigma-dark-invariants/utils/Pretty.sol @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +///@notice https://github.com/one-hundred-proof/kyberswap-exploit/blob/main/lib/helpers/Pretty.sol +library Strings { + function concat(string memory _base, string memory _value) internal pure returns (string memory) { + bytes memory _baseBytes = bytes(_base); + bytes memory _valueBytes = bytes(_value); + + string memory _tmpValue = new string(_baseBytes.length + _valueBytes.length); + bytes memory _newValue = bytes(_tmpValue); + + uint256 i; + uint256 j; + + for (i = 0; i < _baseBytes.length; i++) { + _newValue[j++] = _baseBytes[i]; + } + + for (i = 0; i < _valueBytes.length; i++) { + _newValue[j++] = _valueBytes[i]; + } + + return string(_newValue); + } +} + +library Pretty { + uint8 constant DEFAULT_DECIMALS = 18; + + function toBitString(uint256 n) external pure returns (string memory) { + return uintToBitString(n, 256); + } + + function toBitString(uint256 n, uint8 decimals) external pure returns (string memory) { + return uintToBitString(n, decimals); + } + + function pretty(uint256 n) external pure returns (string memory) { + return n == type(uint256).max + ? "type(uint256).max" + : n == type(uint128).max ? "type(uint128).max" : _pretty(n, DEFAULT_DECIMALS); + } + + function pretty(bool value) external pure returns (string memory) { + return value ? "true" : "false"; + } + + function pretty(uint256 n, uint8 decimals) external pure returns (string memory) { + return _pretty(n, decimals); + } + + function pretty(int256 n) external pure returns (string memory) { + return _prettyInt(n, DEFAULT_DECIMALS); + } + + function pretty(int256 n, uint8 decimals) external pure returns (string memory) { + return _prettyInt(n, decimals); + } + + function _pretty(uint256 n, uint8 decimals) internal pure returns (string memory) { + bool pastDecimals = decimals == 0; + uint256 place = 0; + uint256 r; // remainder + string memory s = ""; + + while (n != 0) { + r = n % 10; + n /= 10; + place++; + s = Strings.concat(toDigit(r), s); + if (pastDecimals && place % 3 == 0 && n != 0) { + s = Strings.concat("_", s); + } + if (!pastDecimals && place == decimals) { + pastDecimals = true; + place = 0; + s = Strings.concat("_", s); + } + } + if (pastDecimals && place == 0) { + s = Strings.concat("0", s); + } + if (!pastDecimals) { + uint256 i; + uint256 upper = (decimals >= place ? decimals - place : 0); + for (i = 0; i < upper; ++i) { + s = Strings.concat("0", s); + } + s = Strings.concat("0_", s); + } + return s; + } + + function _prettyInt(int256 n, uint8 decimals) internal pure returns (string memory) { + bool isNegative = n < 0; + string memory s = ""; + if (isNegative) { + s = "-"; + } + return Strings.concat(s, _pretty(uint256(isNegative ? -n : n), decimals)); + } + + function toDigit(uint256 n) internal pure returns (string memory) { + if (n == 0) { + return "0"; + } else if (n == 1) { + return "1"; + } else if (n == 2) { + return "2"; + } else if (n == 3) { + return "3"; + } else if (n == 4) { + return "4"; + } else if (n == 5) { + return "5"; + } else if (n == 6) { + return "6"; + } else if (n == 7) { + return "7"; + } else if (n == 8) { + return "8"; + } else if (n == 9) { + return "9"; + } else { + revert("Not in range 0 to 10"); + } + } + + function uintToBitString(uint256 n, uint16 bits) internal pure returns (string memory) { + string memory s = ""; + for (uint256 i; i < bits; i++) { + if (n % 2 == 0) { + s = Strings.concat("0", s); + } else { + s = Strings.concat("1", s); + } + n = n / 2; + } + return s; + } +} diff --git a/test/enigma-dark-invariants/utils/PropertiesAsserts.sol b/test/enigma-dark-invariants/utils/PropertiesAsserts.sol new file mode 100644 index 0000000..6d0fcc1 --- /dev/null +++ b/test/enigma-dark-invariants/utils/PropertiesAsserts.sol @@ -0,0 +1,410 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @notice PropertiesAsserts is a library that provides assertions for properties of Solidity contracts. +/// @dev Added more assertions to the original PropertiesAsserts library. +abstract contract PropertiesAsserts { + event LogUint256(string, uint256); + event LogAddress(string, address); + event LogString(string); + + event AssertFail(string); + event AssertEqFail(string); + event AssertNeqFail(string); + event AssertGeFail(string); + event AssertGtFail(string); + event AssertLeFail(string); + event AssertLtFail(string); + + function assertWithMsg(bool b, string memory reason) internal { + if (!b) { + emit AssertFail(reason); + assert(false); + } + } + + /// @notice asserts that a is equal to b. + function assertEq(uint256 a, uint256 b) internal pure { + if (a != b) { + assert(false); + } + } + + function assertEq(int256 a, int256 b) internal pure { + if (a != b) { + assert(false); + } + } + + //write the function below for address + function assertEq(address a, address b) internal pure { + if (a != b) { + assert(false); + } + } + + // now with a reason parameter + function assertEq(address a, address b, string memory reason) internal { + if (a != b) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, "!=", bStr, ", reason: ", reason); + emit AssertEqFail(string(assertMsg)); + assert(false); + } + } + + /// @notice asserts that a is equal to b. Violations are logged using reason. + function assertEq(uint256 a, uint256 b, string memory reason) internal { + if (a != b) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, "!=", bStr, ", reason: ", reason); + emit AssertEqFail(string(assertMsg)); + assert(false); + } + } + + /// @notice int256 version of assertEq + function assertEq(int256 a, int256 b, string memory reason) internal { + if (a != b) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, "!=", bStr, ", reason: ", reason); + emit AssertEqFail(string(assertMsg)); + assert(false); + } + } + + /// @notice asserts that a is not equal to b. Violations are logged using reason. + function assertNeq(uint256 a, uint256 b, string memory reason) internal { + if (a == b) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, "==", bStr, ", reason: ", reason); + emit AssertNeqFail(string(assertMsg)); + assert(false); + } + } + + /// @notice int256 version of assertNeq + function assertNeq(int256 a, int256 b, string memory reason) internal { + if (a == b) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, "==", bStr, ", reason: ", reason); + emit AssertNeqFail(string(assertMsg)); + assert(false); + } + } + + /// @notice asserts that a is greater than or equal to b. Violations are logged using reason. + function assertGe(uint256 a, uint256 b, string memory reason) internal { + if (!(a >= b)) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, "<", bStr, " failed, reason: ", reason); + emit AssertGeFail(string(assertMsg)); + assert(false); + } + } + + /// @notice int256 version of assertGe + function assertGe(int256 a, int256 b, string memory reason) internal { + if (!(a >= b)) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, "<", bStr, " failed, reason: ", reason); + emit AssertGeFail(string(assertMsg)); + assert(false); + } + } + + /// @notice asserts that a is greater than b. Violations are logged using reason. + function assertGt(uint256 a, uint256 b, string memory reason) internal { + if (!(a > b)) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, "<=", bStr, " failed, reason: ", reason); + emit AssertGtFail(string(assertMsg)); + assert(false); + } + } + + /// @notice int256 version of assertGt + function assertGt(int256 a, int256 b, string memory reason) internal { + if (!(a > b)) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, "<=", bStr, " failed, reason: ", reason); + emit AssertGtFail(string(assertMsg)); + assert(false); + } + } + + /// @notice asserts that a is less than or equal to b. Violations are logged using reason. + function assertLe(uint256 a, uint256 b, string memory reason) internal { + if (!(a <= b)) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, ">", bStr, " failed, reason: ", reason); + emit AssertLeFail(string(assertMsg)); + assert(false); + } + } + + /// @notice int256 version of assertLe + function assertLe(int256 a, int256 b, string memory reason) internal { + if (!(a <= b)) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, ">", bStr, " failed, reason: ", reason); + emit AssertLeFail(string(assertMsg)); + assert(false); + } + } + + /// @notice asserts that a is less than b. Violations are logged using reason. + function assertLt(uint256 a, uint256 b, string memory reason) internal { + if (!(a < b)) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, ">=", bStr, " failed, reason: ", reason); + emit AssertLtFail(string(assertMsg)); + assert(false); + } + } + + /// @notice int256 version of assertLt + function assertLt(int256 a, int256 b, string memory reason) internal { + if (!(a < b)) { + string memory aStr = PropertiesLibString.toString(a); + string memory bStr = PropertiesLibString.toString(b); + bytes memory assertMsg = abi.encodePacked("Invalid: ", aStr, ">=", bStr, " failed, reason: ", reason); + emit AssertLtFail(string(assertMsg)); + assert(false); + } + } + + /// @notice Clamps value to be between low and high, both inclusive + function clampBetween(uint256 value, uint256 low, uint256 high) internal returns (uint256) { + if (value < low || value > high) { + uint256 ans = low + (value % (high - low + 1)); + string memory valueStr = PropertiesLibString.toString(value); + string memory ansStr = PropertiesLibString.toString(ans); + bytes memory message = abi.encodePacked("Clamping value ", valueStr, " to ", ansStr); + emit LogString(string(message)); + return ans; + } + return value; + } + + /// @notice int256 version of clampBetween + function clampBetween(int256 value, int256 low, int256 high) internal returns (int256) { + if (value < low || value > high) { + int256 range = high - low + 1; + int256 clamped = (value - low) % (range); + if (clamped < 0) clamped += range; + int256 ans = low + clamped; + string memory valueStr = PropertiesLibString.toString(value); + string memory ansStr = PropertiesLibString.toString(ans); + bytes memory message = abi.encodePacked("Clamping value ", valueStr, " to ", ansStr); + emit LogString(string(message)); + return ans; + } + return value; + } + + /// @notice clamps a to be less than b + function clampLt(uint256 a, uint256 b) internal returns (uint256) { + if (!(a < b)) { + assertNeq(b, 0, "clampLt cannot clamp value a to be less than zero. Check your inputs/assumptions."); + uint256 value = a % b; + string memory aStr = PropertiesLibString.toString(a); + string memory valueStr = PropertiesLibString.toString(value); + bytes memory message = abi.encodePacked("Clamping value ", aStr, " to ", valueStr); + emit LogString(string(message)); + return value; + } + return a; + } + + /// @notice int256 version of clampLt + function clampLt(int256 a, int256 b) internal returns (int256) { + if (!(a < b)) { + int256 value = b - 1; + string memory aStr = PropertiesLibString.toString(a); + string memory valueStr = PropertiesLibString.toString(value); + bytes memory message = abi.encodePacked("Clamping value ", aStr, " to ", valueStr); + emit LogString(string(message)); + return value; + } + return a; + } + + /// @notice clamps a to be less than or equal to b + function clampLe(uint256 a, uint256 b) internal returns (uint256) { + if (!(a <= b)) { + uint256 value = a % (b + 1); + string memory aStr = PropertiesLibString.toString(a); + string memory valueStr = PropertiesLibString.toString(value); + bytes memory message = abi.encodePacked("Clamping value ", aStr, " to ", valueStr); + emit LogString(string(message)); + return value; + } + return a; + } + + /// @notice int256 version of clampLe + function clampLe(int256 a, int256 b) internal returns (int256) { + if (!(a <= b)) { + int256 value = b; + string memory aStr = PropertiesLibString.toString(a); + string memory valueStr = PropertiesLibString.toString(value); + bytes memory message = abi.encodePacked("Clamping value ", aStr, " to ", valueStr); + emit LogString(string(message)); + return value; + } + return a; + } + + /// @notice clamps a to be greater than b + function clampGt(uint256 a, uint256 b) internal returns (uint256) { + if (!(a > b)) { + assertNeq( + b, + type(uint256).max, + "clampGt cannot clamp value a to be larger than uint256.max. Check your inputs/assumptions." + ); + uint256 value = b + 1; + string memory aStr = PropertiesLibString.toString(a); + string memory valueStr = PropertiesLibString.toString(value); + bytes memory message = abi.encodePacked("Clamping value ", aStr, " to ", valueStr); + emit LogString(string(message)); + return value; + } else { + return a; + } + } + + /// @notice int256 version of clampGt + function clampGt(int256 a, int256 b) internal returns (int256) { + if (!(a > b)) { + int256 value = b + 1; + string memory aStr = PropertiesLibString.toString(a); + string memory valueStr = PropertiesLibString.toString(value); + bytes memory message = abi.encodePacked("Clamping value ", aStr, " to ", valueStr); + emit LogString(string(message)); + return value; + } else { + return a; + } + } + + /// @notice clamps a to be greater than or equal to b + function clampGe(uint256 a, uint256 b) internal returns (uint256) { + if (!(a > b)) { + uint256 value = b; + string memory aStr = PropertiesLibString.toString(a); + string memory valueStr = PropertiesLibString.toString(value); + bytes memory message = abi.encodePacked("Clamping value ", aStr, " to ", valueStr); + emit LogString(string(message)); + return value; + } + return a; + } + + /// @notice int256 version of clampGe + function clampGe(int256 a, int256 b) internal returns (int256) { + if (!(a > b)) { + int256 value = b; + string memory aStr = PropertiesLibString.toString(a); + string memory valueStr = PropertiesLibString.toString(value); + bytes memory message = abi.encodePacked("Clamping value ", aStr, " to ", valueStr); + emit LogString(string(message)); + return value; + } + return a; + } +} + +/// @notice Efficient library for creating string representations of integers. +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) +/// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibString.sol) +/// @dev Name of the library is modified to prevent collisions with contract-under-test uses of LibString +library PropertiesLibString { + function toString(int256 value) internal pure returns (string memory str) { + uint256 absValue = value >= 0 ? uint256(value) : uint256(-value); + str = toString(absValue); + + if (value < 0) { + str = string(abi.encodePacked("-", str)); + } + } + + function toString(uint256 value) internal pure returns (string memory str) { + /// @solidity memory-safe-assembly + assembly { + // The maximum value of a uint256 contains 78 digits (1 byte per digit), but we allocate 160 bytes + // to keep the free memory pointer word aligned. We'll need 1 word for the length, 1 word for the + // trailing zeros padding, and 3 other words for a max of 78 digits. In total: 5 * 32 = 160 bytes. + let newFreeMemoryPointer := add(mload(0x40), 160) + + // Update the free memory pointer to avoid overriding our string. + mstore(0x40, newFreeMemoryPointer) + + // Assign str to the end of the zone of newly allocated memory. + str := sub(newFreeMemoryPointer, 32) + + // Clean the last word of memory it may not be overwritten. + mstore(str, 0) + + // Cache the end of the memory to calculate the length later. + let end := str + + // We write the string from rightmost digit to leftmost digit. + // The following is essentially a do-while loop that also handles the zero case. + // prettier-ignore + for { let temp := value } 1 {} { + // Move the pointer 1 byte to the left. + str := sub(str, 1) + + // Write the character to the pointer. + // The ASCII index of the '0' character is 48. + mstore8(str, add(48, mod(temp, 10))) + + // Keep dividing temp until zero. + temp := div(temp, 10) + + // prettier-ignore + if iszero(temp) { break } + } + + // Compute and cache the final total length of the string. + let length := sub(end, str) + + // Move the pointer 32 bytes leftwards to make room for the length. + str := sub(str, 32) + + // Store the string's length at the start of memory allocated for our string. + mstore(str, length) + } + } + + function toString(address value) internal pure returns (string memory str) { + bytes memory s = new bytes(40); + for (uint256 i = 0; i < 20; i++) { + bytes1 b = bytes1(uint8(uint256(uint160(value)) / (2 ** (8 * (19 - i))))); + bytes1 hi = bytes1(uint8(b) / 16); + bytes1 lo = bytes1(uint8(b) - 16 * uint8(hi)); + s[2 * i] = char(hi); + s[2 * i + 1] = char(lo); + } + return string(s); + } + + function char(bytes1 b) internal pure returns (bytes1 c) { + if (uint8(b) < 10) return bytes1(uint8(b) + 0x30); + else return bytes1(uint8(b) + 0x57); + } +} diff --git a/test/enigma-dark-invariants/utils/PropertiesConstants.sol b/test/enigma-dark-invariants/utils/PropertiesConstants.sol new file mode 100644 index 0000000..cfea635 --- /dev/null +++ b/test/enigma-dark-invariants/utils/PropertiesConstants.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +abstract contract PropertiesConstants { + // Constant echidna addresses + address constant USER1 = address(0x10000); + address constant USER2 = address(0x20000); + address constant USER3 = address(0x30000); + uint256 constant INITIAL_BALANCE = 1000e30; + uint256 constant INTEREST_SMEAR = 2 weeks; +} diff --git a/test/enigma-dark-invariants/utils/StdAsserts.sol b/test/enigma-dark-invariants/utils/StdAsserts.sol new file mode 100644 index 0000000..e43d10e --- /dev/null +++ b/test/enigma-dark-invariants/utils/StdAsserts.sol @@ -0,0 +1,443 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {PropertiesAsserts} from "./PropertiesAsserts.sol"; +import {stdMath} from "forge-std/StdMath.sol"; + +/// @notice Standardized assertions for use in Invariant tests, inherits PropertiesAsserts +/// @dev Adapted from forge to work with echidna & medusa +abstract contract StdAsserts is PropertiesAsserts { + event log(string); + event logs(bytes); + + event log_address(address); + event log_bytes32(bytes32); + event log_int(int256); + event log_uint(uint256); + event log_bytes(bytes); + event log_string(string); + + event log_named_address(string key, address val); + event log_named_bytes32(string key, bytes32 val); + event log_named_decimal_int(string key, int256 val, uint256 decimals); + event log_named_decimal_uint(string key, uint256 val, uint256 decimals); + event log_named_int(string key, int256 val); + event log_named_uint(string key, uint256 val); + event log_named_bytes(string key, bytes val); + event log_named_string(string key, string val); + event log_array(uint256[] val); + event log_array(int256[] val); + event log_array(address[] val); + event log_named_array(string key, uint256[] val); + event log_named_array(string key, int256[] val); + event log_named_array(string key, address[] val); + + function fail(string memory err) internal virtual { + emit log_named_string("Error", err); + fail(); + } + + function fail() internal virtual { + assert(false); + } + + function assertTrue(bool condition) internal { + if (!condition) { + emit log("Error: Assertion Failed"); + fail(); + } + } + + function assertTrue(bool condition, string memory err) internal { + if (!condition) { + emit log_named_string("Error", err); + assertTrue(condition); + } + } + + function assertFalse(bool data) internal virtual { + assertTrue(!data); + } + + function assertFalse(bool data, string memory err) internal virtual { + assertTrue(!data, err); + } + + function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) { + ok = true; + if (a.length == b.length) { + for (uint256 i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + ok = false; + } + } + } else { + ok = false; + } + } + + function assertEq0(bytes memory a, bytes memory b) internal { + if (!checkEq0(a, b)) { + emit log("Error: a == b not satisfied [bytes]"); + emit log_named_bytes(" Expected", a); + emit log_named_bytes(" Actual", b); + fail(); + } + } + + function assertEq0(bytes memory a, bytes memory b, string memory err) internal { + if (!checkEq0(a, b)) { + emit log_named_string("Error", err); + assertEq0(a, b); + } + } + + function assertEq(bool a, bool b) internal virtual { + if (a != b) { + emit log("Error: a == b not satisfied [bool]"); + emit log_named_string(" Left", a ? "true" : "false"); + emit log_named_string(" Right", b ? "true" : "false"); + fail(); + } + } + + function assertEq(bool a, bool b, string memory err) internal virtual { + if (a != b) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + function assertEq(bytes memory a, bytes memory b) internal virtual { + assertEq0(a, b); + } + + function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual { + assertEq0(a, b, err); + } + + function assertEq(uint256[] memory a, uint256[] memory b) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log("Error: a == b not satisfied [uint[]]"); + emit log_named_array(" Left", a); + emit log_named_array(" Right", b); + fail(); + } + } + + function assertEq(int256[] memory a, int256[] memory b) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log("Error: a == b not satisfied [int[]]"); + emit log_named_array(" Left", a); + emit log_named_array(" Right", b); + fail(); + } + } + + function assertEq(address[] memory a, address[] memory b) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log("Error: a == b not satisfied [address[]]"); + emit log_named_array(" Left", a); + emit log_named_array(" Right", b); + fail(); + } + } + + function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + // Legacy helper + function assertEqUint(uint256 a, uint256 b) internal virtual { + assertEq(uint256(a), uint256(b)); + } + + function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log("Error: a ~= b not satisfied [uint]"); + emit log_named_uint(" Left", a); + emit log_named_uint(" Right", b); + emit log_named_uint(" Max Delta", maxDelta); + emit log_named_uint(" Delta", delta); + fail(); + } + } + + function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log_named_string("Error", err); + assertApproxEqAbs(a, b, maxDelta); + } + } + + function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log("Error: a ~= b not satisfied [uint]"); + emit log_named_decimal_uint(" Left", a, decimals); + emit log_named_decimal_uint(" Right", b, decimals); + emit log_named_decimal_uint(" Max Delta", maxDelta, decimals); + emit log_named_decimal_uint(" Delta", delta, decimals); + fail(); + } + } + + function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, string memory err) + internal + virtual + { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log_named_string("Error", err); + assertApproxEqAbsDecimal(a, b, maxDelta, decimals); + } + } + + function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log("Error: a ~= b not satisfied [int]"); + emit log_named_int(" Left", a); + emit log_named_int(" Right", b); + emit log_named_uint(" Max Delta", maxDelta); + emit log_named_uint(" Delta", delta); + fail(); + } + } + + function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log_named_string("Error", err); + assertApproxEqAbs(a, b, maxDelta); + } + } + + function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log("Error: a ~= b not satisfied [int]"); + emit log_named_decimal_int(" Left", a, decimals); + emit log_named_decimal_int(" Right", b, decimals); + emit log_named_decimal_uint(" Max Delta", maxDelta, decimals); + emit log_named_decimal_uint(" Delta", delta, decimals); + fail(); + } + } + + function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, string memory err) + internal + virtual + { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log_named_string("Error", err); + assertApproxEqAbsDecimal(a, b, maxDelta, decimals); + } + } + + function assertApproxEqRel( + uint256 a, + uint256 b, + uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% + ) internal virtual { + if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log("Error: a ~= b not satisfied [uint]"); + emit log_named_uint(" Left", a); + emit log_named_uint(" Right", b); + emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); + emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); + fail(); + } + } + + function assertApproxEqRel( + uint256 a, + uint256 b, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + string memory err + ) internal virtual { + if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log_named_string("Error", err); + assertApproxEqRel(a, b, maxPercentDelta); + } + } + + function assertApproxEqRelDecimal( + uint256 a, + uint256 b, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals + ) internal virtual { + if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log("Error: a ~= b not satisfied [uint]"); + emit log_named_decimal_uint(" Left", a, decimals); + emit log_named_decimal_uint(" Right", b, decimals); + emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); + emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); + fail(); + } + } + + function assertApproxEqRelDecimal( + uint256 a, + uint256 b, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals, + string memory err + ) internal virtual { + if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log_named_string("Error", err); + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); + } + } + + function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual { + if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log("Error: a ~= b not satisfied [int]"); + emit log_named_int(" Left", a); + emit log_named_int(" Right", b); + emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); + emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); + fail(); + } + } + + function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual { + if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log_named_string("Error", err); + assertApproxEqRel(a, b, maxPercentDelta); + } + } + + function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals) internal virtual { + if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log("Error: a ~= b not satisfied [int]"); + emit log_named_decimal_int(" Left", a, decimals); + emit log_named_decimal_int(" Right", b, decimals); + emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); + emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); + fail(); + } + } + + function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, string memory err) + internal + virtual + { + if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log_named_string("Error", err); + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); + } + } + + function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual { + assertEqCall(target, callDataA, target, callDataB, true); + } + + function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB) + internal + virtual + { + assertEqCall(targetA, callDataA, targetB, callDataB, true); + } + + function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData) + internal + virtual + { + assertEqCall(target, callDataA, target, callDataB, strictRevertData); + } + + function assertEqCall( + address targetA, + bytes memory callDataA, + address targetB, + bytes memory callDataB, + bool strictRevertData + ) internal virtual { + (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA); + (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB); + + if (successA && successB) { + assertEq(returnDataA, returnDataB, "Call return data does not match"); + } + + if (!successA && !successB && strictRevertData) { + assertEq(returnDataA, returnDataB, "Call revert data does not match"); + } + + if (!successA && successB) { + emit log("Error: Calls were not equal"); + emit log_named_bytes(" Left call revert data", returnDataA); + emit log_named_bytes(" Right call return data", returnDataB); + fail(); + } + + if (successA && !successB) { + emit log("Error: Calls were not equal"); + emit log_named_bytes(" Left call return data", returnDataA); + emit log_named_bytes(" Right call revert data", returnDataB); + fail(); + } + } +} diff --git a/test/enigma-dark-invariants/utils/mocks/MockPriceOracle.sol b/test/enigma-dark-invariants/utils/mocks/MockPriceOracle.sol new file mode 100644 index 0000000..7920d50 --- /dev/null +++ b/test/enigma-dark-invariants/utils/mocks/MockPriceOracle.sol @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +import "evk/EVault/IEVault.sol"; + +contract MockPriceOracle { + error PO_BaseUnsupported(); + error PO_QuoteUnsupported(); + error PO_Overflow(); + error PO_NoPath(); + + mapping(address base => mapping(address quote => uint256)) price; + mapping(address base => mapping(address quote => Prices)) prices; + + struct Prices { + bool set; + uint256 bid; + uint256 ask; + } + + function name() external pure returns (string memory) { + return "MockPriceOracle"; + } + + function getQuote(uint256 amount, address base, address quote) public view returns (uint256 out) { + return calculateQuote(base, amount, price[resolveUnderlying(base)][quote]); + } + + function getQuotes(uint256 amount, address base, address quote) + external + view + returns (uint256 bidOut, uint256 askOut) + { + if (prices[resolveUnderlying(base)][quote].set) { + return ( + calculateQuote(base, amount, prices[resolveUnderlying(base)][quote].bid), + calculateQuote(base, amount, prices[resolveUnderlying(base)][quote].ask) + ); + } + + bidOut = askOut = getQuote(amount, base, quote); + } + + ///// Mock functions + + function setPrice(address base, address quote, uint256 newPrice) external { + price[resolveUnderlying(base)][quote] = newPrice; + } + + function setPrices(address base, address quote, uint256 newBid, uint256 newAsk) external { + prices[resolveUnderlying(base)][quote] = Prices({set: true, bid: newBid, ask: newAsk}); + } + + function calculateQuote(address base, uint256 amount, uint256 p) internal view returns (uint256) { + // While base is a vault (for the purpose of the mock, if it implements asset()), then call + // convertToAssets() to price its shares. This is similar to how EulerRouter implements + // "resolved" vaults. + + while (base.code.length > 0) { + (bool success, bytes memory data) = base.staticcall(abi.encodeCall(IERC4626.asset, ())); + if (!success) break; + + (address asset) = abi.decode(data, (address)); + amount = IEVault(base).convertToAssets(amount); + base = asset; + } + + return amount * p / 1e18; + } + + function resolveUnderlying(address asset) internal view returns (address) { + if (asset.code.length > 0) { + (bool success, bytes memory data) = asset.staticcall(abi.encodeCall(IERC4626.asset, ())); + if (success) return abi.decode(data, (address)); + } + + return asset; + } +} diff --git a/test/enigma-dark-invariants/utils/mocks/TestERC20.sol b/test/enigma-dark-invariants/utils/mocks/TestERC20.sol new file mode 100644 index 0000000..b1c54b8 --- /dev/null +++ b/test/enigma-dark-invariants/utils/mocks/TestERC20.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {MockERC20} from "forge-std/mocks/MockERC20.sol"; + +contract TestERC20 is MockERC20 { + constructor(string memory name, string memory symbol, uint8 decimals) { + initialize(name, symbol, decimals); + } + + function mint(address to, uint256 value) public virtual { + _mint(to, value); + } + + function burn(address from, uint256 value) public virtual { + _burn(from, value); + } +} From 9c7f484fb52effbe47ef4ca1f8f4a1d2fdb39341 Mon Sep 17 00:00:00 2001 From: Elpacos Date: Thu, 26 Dec 2024 15:59:03 +0100 Subject: [PATCH 02/18] chore: add roundtrip handler and nav invariants --- .../workflows/echidna-enigma-invariants.yml | 46 +++++++ Makefile | 13 ++ .../CryticToFoundry.t.sol | 7 +- test/enigma-dark-invariants/Invariants.t.sol | 2 + test/enigma-dark-invariants/Setup.t.sol | 96 ++++++++++---- test/enigma-dark-invariants/Tester.t.sol | 2 +- .../_config/echidna_config.yaml | 12 +- .../_config/echidna_config_ci.yaml | 4 +- .../base/BaseStorage.t.sol | 12 +- .../base/BaseTest.t.sol | 25 ++++ .../handlers/swap/MaglevHandler.t.sol | 119 +++++++++++++++++- .../hooks/DefaultBeforeAfterHooks.t.sol | 19 ++- .../invariants/BaseInvariants.t.sol | 4 +- .../specs/InvariantsSpec.t.sol | 2 +- .../specs/PostconditionsSpec.t.sol | 8 +- 15 files changed, 319 insertions(+), 52 deletions(-) create mode 100644 .github/workflows/echidna-enigma-invariants.yml create mode 100644 Makefile diff --git a/.github/workflows/echidna-enigma-invariants.yml b/.github/workflows/echidna-enigma-invariants.yml new file mode 100644 index 0000000..11abd75 --- /dev/null +++ b/.github/workflows/echidna-enigma-invariants.yml @@ -0,0 +1,46 @@ +name: Echidna Enigma Invariants + +on: + push: + branches: + - main + pull_request: + +env: + FOUNDRY_PROFILE: ci + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + echidna: + runs-on: ubuntu-latest + + strategy: + matrix: + mode: [property, assertion] # Define the modes here + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Compile contracts + run: | + forge build --build-info + + - name: Run Echidna ${{ matrix.mode == 'property' && 'Property' || 'Assertion' }} Mode + uses: crytic/echidna-action@v2 + with: + files: . + contract: Tester + config: test/enigma-dark-invariants/_config/echidna_config_ci.yaml + crytic-args: --ignore-compile + test-mode: ${{ matrix.mode == 'assertion' && 'assertion' || '' }} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..797fa2c --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +# Invariants +echidna: + echidna test/enigma-dark-invariants/Tester.t.sol --contract Tester --config ./test/enigma-dark-invariants/_config/echidna_config.yaml --corpus-dir ./test/enigma-dark-invariants/_corpus/echidna/default/_data/corpus + +echidna-assert: + echidna test/enigma-dark-invariants/Tester.t.sol --contract Tester --test-mode assertion --config ./test/enigma-dark-invariants/_config/echidna_config.yaml --corpus-dir ./test/enigma-dark-invariants/_corpus/echidna/default/_data/corpus + +echidna-explore: + echidna test/enigma-dark-invariants/Tester.t.sol --contract Tester --test-mode exploration --config ./test/enigma-dark-invariants/_config/echidna_config.yaml --corpus-dir ./test/enigma-dark-invariants/_corpus/echidna/default/_data/corpus + +# Medusa +medusa: + medusa fuzz --config ./medusa.json \ No newline at end of file diff --git a/test/enigma-dark-invariants/CryticToFoundry.t.sol b/test/enigma-dark-invariants/CryticToFoundry.t.sol index fba2ad2..63b4545 100644 --- a/test/enigma-dark-invariants/CryticToFoundry.t.sol +++ b/test/enigma-dark-invariants/CryticToFoundry.t.sol @@ -22,7 +22,7 @@ contract CryticToFoundry is Invariants, Setup { function setUp() public { // Deploy protocol contracts - _setUp(); + _setUp(Curve.EULER_SWAP); // Initialize handler contracts _setUpHandlers(); @@ -39,6 +39,11 @@ contract CryticToFoundry is Invariants, Setup { /// @dev Needed in order for foundry to recognise the contract as a test, faster debugging function testAux() public {} + function test_replaySwap() public { + Tester.mint(2000000, 0, 0); + Tester.swap(1, 0, 0, 0, 0);//@audit-issue is possible to extract value from the protocol 1 wei of value + } + /////////////////////////////////////////////////////////////////////////////////////////////// // POSTCONDITIONS REPLAY // /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/Invariants.t.sol b/test/enigma-dark-invariants/Invariants.t.sol index f01f07f..c55b058 100644 --- a/test/enigma-dark-invariants/Invariants.t.sol +++ b/test/enigma-dark-invariants/Invariants.t.sol @@ -17,6 +17,8 @@ abstract contract Invariants is BaseInvariants { /////////////////////////////////////////////////////////////////////////////////////////////// function echidna_BASE_ASSETS_INVARIANTS() public returns (bool) { + assert_INV_BASE_A(); + return true; } } diff --git a/test/enigma-dark-invariants/Setup.t.sol b/test/enigma-dark-invariants/Setup.t.sol index 709b4f6..5e95556 100644 --- a/test/enigma-dark-invariants/Setup.t.sol +++ b/test/enigma-dark-invariants/Setup.t.sol @@ -16,7 +16,9 @@ import {Base} from "evk/EVault/shared/Base.sol"; import {Dispatch} from "evk/EVault/Dispatch.sol"; import {EVault} from "evk/EVault/EVault.sol"; import {MaglevBase} from "src/MaglevBase.sol"; -import {MaglevEulerSwap as Maglev} from "src/MaglevEulerSwap.sol"; +import {MaglevConstantSum} from "src/MaglevConstantSum.sol"; +import {MaglevConstantProduct} from "src/MaglevConstantProduct.sol"; +import {MaglevEulerSwap} from "src/MaglevEulerSwap.sol"; // Modules import {Initialize} from "evk/EVault/modules/Initialize.sol"; @@ -42,7 +44,7 @@ import {Actor} from "./utils/Actor.sol"; /// @notice Setup contract for the invariant test Suite, inherited by Tester contract Setup is BaseTest { - function _setUp() internal { + function _setUp(Curve _curveType) internal { // Deploy protocol contracts and protocol actors _deployEulerEnvContracts(); @@ -53,7 +55,7 @@ contract Setup is BaseTest { _setUpActors(); // Deploy and setup maglev - _deployMaglev(); + _deployMaglev(_curveType); } /// @notice Deploy euler env contracts @@ -74,6 +76,10 @@ contract Setup is BaseTest { sequenceRegistry = address(new SequenceRegistry()); } + /////////////////////////////////////////////////////////////////////////////////////////////// + // VAULTS // + /////////////////////////////////////////////////////////////////////////////////////////////// + function _deployVaults() internal { // Deploy the modules Base.Integrations memory integrations = @@ -112,34 +118,51 @@ contract Setup is BaseTest { vaults.push(address(eTST2)); } - function _deployMaglev() internal { + function _deployEVault(address asset) internal returns (IEVault eVault) { + // Deploy the eTST + eVault = IEVault(factory.createProxy(address(0), true, abi.encodePacked(asset, address(oracle), address(1)))); + + // Configure the vault + eVault.setHookConfig(address(0), 0); + eVault.setInterestRateModel(address(new IRMTestDefault())); + eVault.setMaxLiquidationDiscount(0.2e4); + eVault.setFeeReceiver(feeRecipient); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // MAGLEV // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function _deployMaglev(Curve _curveType) internal { // Setup maglev lp as the first actor - maglevLp = address(actors[USER1]); + holder = address(actors[USER1]); + + /// @dev store the curve selected + curve = _curveType; - // Setup the maglev params∫ + // Setup the maglev params MaglevBase.BaseParams memory baseParams = MaglevBase.BaseParams({ evc: address(evc), vault0: address(eTST), vault1: address(eTST2), - myAccount: maglevLp, + myAccount: holder, debtLimit0: 50e18, // TODO tweak these numbers debtLimit1: 50e18, fee: 0 }); - // Deploy the maglev contract - maglev = IMaglevBase( - address( - new Maglev( - baseParams, - Maglev.EulerSwapParams({priceX: 1e18, priceY: 1e18, concentrationX: 0.4e18, concentrationY: 0.85e18}) - ) - ) - ); + /// @dev Switch between the different curves + if (curve == Curve.EULER_SWAP) { + _deployMaglevEulerSwap(baseParams); + } else if (curve == Curve.PRODUCT) { + _deployMaglevConstantProduct(baseParams); + } else { + _deployMaglevConstantSum(baseParams); + } // Set maglev as operator for the lp and call configure - vm.prank(maglevLp); - evc.setAccountOperator(maglevLp, address(maglev), true); + vm.prank(holder); + evc.setAccountOperator(holder, address(maglev), true); maglev.configure(); // Setup actors token approvals to maglev @@ -149,17 +172,38 @@ contract Setup is BaseTest { _setupActorApprovals(baseAssets, contracts); } - function _deployEVault(address asset) internal returns (IEVault eVault) { - // Deploy the eTST - eVault = IEVault(factory.createProxy(address(0), true, abi.encodePacked(asset, address(oracle), address(1)))); + function _deployMaglevEulerSwap(MaglevBase.BaseParams memory _baseParams) internal { + maglev = IMaglevBase( + address( + new MaglevEulerSwap( + _baseParams, + MaglevEulerSwap.EulerSwapParams({ + priceX: 1e18, + priceY: 1e18, + concentrationX: 0.4e18, + concentrationY: 0.85e18 + }) + ) + ) + ); + } - // Configure the vault - eVault.setHookConfig(address(0), 0); - eVault.setInterestRateModel(address(new IRMTestDefault())); - eVault.setMaxLiquidationDiscount(0.2e4); - eVault.setFeeReceiver(feeRecipient); + function _deployMaglevConstantProduct(MaglevBase.BaseParams memory _baseParams) internal { + maglev = IMaglevBase(address(new MaglevConstantProduct(_baseParams))); + } + + function _deployMaglevConstantSum(MaglevBase.BaseParams memory _baseParams) internal { + maglev = IMaglevBase( + address( + new MaglevConstantSum(_baseParams, MaglevConstantSum.ConstantSumParams({priceX: 1e18, priceY: 1e18})) + ) + ); } + /////////////////////////////////////////////////////////////////////////////////////////////// + // ACTORS // + /////////////////////////////////////////////////////////////////////////////////////////////// + /// @notice Deploy protocol actors and initialize their balances function _setUpActors() internal { // Initialize the three actors of the fuzzers diff --git a/test/enigma-dark-invariants/Tester.t.sol b/test/enigma-dark-invariants/Tester.t.sol index b015666..8a9a394 100644 --- a/test/enigma-dark-invariants/Tester.t.sol +++ b/test/enigma-dark-invariants/Tester.t.sol @@ -16,7 +16,7 @@ contract Tester is Invariants, Setup { /// @dev Foundry compatibility faster setup debugging function setUp() internal { // Deploy protocol contracts and protocol actors - _setUp(); + _setUp(Curve.EULER_SWAP); // Initialize handler contracts _setUpHandlers(); diff --git a/test/enigma-dark-invariants/_config/echidna_config.yaml b/test/enigma-dark-invariants/_config/echidna_config.yaml index d7276b0..1616117 100644 --- a/test/enigma-dark-invariants/_config/echidna_config.yaml +++ b/test/enigma-dark-invariants/_config/echidna_config.yaml @@ -6,9 +6,9 @@ codeSize: 224576 #multi-abi: true #balanceAddr is default balance for addresses -balanceAddr: 0xffffffffffffffffffffffff +balanceAddr: 0x1000000000000000000000000 #balanceContract overrides balanceAddr for the contract address (2^128 = ~3e38) -balanceContract: 0xffffffffffffffffffffffffffffffffffffffffffffffff +balanceContract: 0x1000000000000000000000000000000000000000000000000 #testLimit is the number of test sequences to run testLimit: 20000000 @@ -37,7 +37,7 @@ stopOnFail: false coverage: true # list of file formats to save coverage reports in; default is all possible formats -coverageFormats: ["lcov", "html"] +coverageFormats: [ "lcov", "html" ] #directory to save the corpus; by default is disabled corpusDir: "test/invariants/_corpus/echidna/default/_data/corpus" @@ -45,12 +45,10 @@ corpusDir: "test/invariants/_corpus/echidna/default/_data/corpus" #mutConsts: [100, 1, 1] #remappings -cryticArgs: ["--solc-remaps", "@crytic/properties/=lib/properties/ forge-std/=lib/forge-std/src/ ds-test/=lib/forge-std/lib/ds-test/src/ openzeppelin/=lib/openzeppelin-contracts/contracts/", "--compile-libraries=(Pretty,0xf01),(Strings,0xf02)"] - -deployContracts: [["0xf01", "Pretty"], ["0xf02", "Strings"]] +cryticArgs: [ "--solc-remaps", "@crytic/properties/=lib/properties/ forge-std/=lib/forge-std/src/ ds-test/=lib/forge-std/lib/ds-test/src/ openzeppelin/=lib/openzeppelin-contracts/contracts/" ] # maximum value to send to payable functions -maxValue: 100000000000000000000000 # 100000 eth +maxValue: 1e+23 # 100000 eth #quiet produces (much) less verbose output quiet: false diff --git a/test/enigma-dark-invariants/_config/echidna_config_ci.yaml b/test/enigma-dark-invariants/_config/echidna_config_ci.yaml index e73a2bb..cfd37a9 100644 --- a/test/enigma-dark-invariants/_config/echidna_config_ci.yaml +++ b/test/enigma-dark-invariants/_config/echidna_config_ci.yaml @@ -45,9 +45,7 @@ corpusDir: "corpus" #mutConsts: [100, 1, 1] #remappings -cryticArgs: [ "--solc-remaps", "@crytic/properties/=lib/properties/ forge-std/=lib/forge-std/src/ ds-test/=lib/forge-std/lib/ds-test/src/ openzeppelin/=lib/openzeppelin-contracts/contracts/", "--compile-libraries=(Pretty,0xf01),(Strings,0xf02)" ] - -deployContracts: [ [ "0xf01", "Pretty" ], [ "0xf02", "Strings" ] ] +cryticArgs: [ "--solc-remaps", "@crytic/properties/=lib/properties/ forge-std/=lib/forge-std/src/ ds-test/=lib/forge-std/lib/ds-test/src/ openzeppelin/=lib/openzeppelin-contracts/contracts/" ] # maximum value to send to payable functions maxValue: 1e+23 # 100000 eth diff --git a/test/enigma-dark-invariants/base/BaseStorage.t.sol b/test/enigma-dark-invariants/base/BaseStorage.t.sol index 4da7d9a..663d9fb 100644 --- a/test/enigma-dark-invariants/base/BaseStorage.t.sol +++ b/test/enigma-dark-invariants/base/BaseStorage.t.sol @@ -54,7 +54,7 @@ abstract contract BaseStorage { address internal targetActor; /// @notice The account that owns the maglev liqudity - address internal maglevLp; + address internal holder; address internal feeRecipient; @@ -88,6 +88,10 @@ abstract contract BaseStorage { address balanceTracker; address sequenceRegistry; + /// @notice curve selector + + Curve curve; + /////////////////////////////////////////////////////////////////////////////////////////////// // EXTRA VARIABLES // /////////////////////////////////////////////////////////////////////////////////////////////// @@ -107,4 +111,10 @@ abstract contract BaseStorage { /////////////////////////////////////////////////////////////////////////////////////////////// // STRUCTS // /////////////////////////////////////////////////////////////////////////////////////////////// + + enum Curve { + EULER_SWAP, + PRODUCT, + SUM + } } diff --git a/test/enigma-dark-invariants/base/BaseTest.t.sol b/test/enigma-dark-invariants/base/BaseTest.t.sol index 2d08e38..0c1b41e 100644 --- a/test/enigma-dark-invariants/base/BaseTest.t.sol +++ b/test/enigma-dark-invariants/base/BaseTest.t.sol @@ -103,4 +103,29 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU assert(success); if (retdata.length > 0) assert(abi.decode(retdata, (bool))); } + + function _transferByActor(address token, address to, uint256 amount) internal { + bool success; + bytes memory returnData; + (success, returnData) = actor.proxy(token, abi.encodeWithSelector(IERC20.transfer.selector, to, amount)); + require(success, string(returnData)); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // MAGLEV SPECIFIC HELPERS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function _getHolderNAV() public view returns (int256) { + uint256 balance0 = eTST.convertToAssets(eTST.balanceOf(holder)); + uint256 debt0 = eTST.debtOf(holder); + uint256 balance1 = eTST2.convertToAssets(eTST2.balanceOf(holder)); + uint256 debt1 = eTST2.debtOf(holder); + + uint256 balValue = oracle.getQuote(balance0, address(assetTST), unitOfAccount) + + oracle.getQuote(balance1, address(assetTST2), unitOfAccount); + uint256 debtValue = oracle.getQuote(debt0, address(assetTST), unitOfAccount) + + oracle.getQuote(debt1, address(assetTST2), unitOfAccount); + + return int256(balValue) - int256(debtValue); + } } diff --git a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol index 92c7b55..001bb94 100644 --- a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol @@ -19,29 +19,140 @@ abstract contract MaglevHandler is BaseHandler { // STATE VARIABLES // /////////////////////////////////////////////////////////////////////////////////////////////// + address roundtripSwapActor; + address receiver; + /////////////////////////////////////////////////////////////////////////////////////////////// // ACTIONS // /////////////////////////////////////////////////////////////////////////////////////////////// - function swap(uint256 amount0Out, uint256 amount1Out, uint8 i) external setup { + function swap(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In, uint8 i) public setup { bool success; bytes memory returnData; // Get one of the three actors randomly - address to = _getRandomActor(i); + receiver = roundtripSwapActor == address(0) ? _getRandomActor(i) : roundtripSwapActor; address target = address(maglev); + require(amount0Out > 1 || amount1Out > 1, "MaglevHandler: Invalid amount out"); + + if (amount0In > 0) { + _transferByActor(address(assetTST), address(maglev), amount0In); + } + + if (amount1In > 0) { + _transferByActor(address(assetTST2), address(maglev), amount1In); + } + _before(); (success, returnData) = - actor.proxy(target, abi.encodeWithSelector(IMaglevBase.swap.selector, amount0Out, amount1Out, to, "")); + actor.proxy(target, abi.encodeWithSelector(IMaglevBase.swap.selector, amount0Out, amount1Out, receiver, "")); + + delete receiver; + + if (roundtripSwapActor != address(0)) require(success); if (success) { _after(); + + _commonPostconditions(amount0Out, amount1Out, amount0In, amount1In); + + if (curve == Curve.EULER_SWAP) { + _eulerSwapPostconditions(); + } else if (curve == Curve.PRODUCT) { + _constantProductPostconditions(); + } else { + _constantSumPostconditions(); + } + + assert(false); + } + } + + function roundtripSwap(uint256 amount, uint8 i) external setup { + uint256 amount0Out; + uint256 amount1Out; + uint256 amount0In; + uint256 amount1In; + + IERC20 assetTSTIn = IERC20(_getRandomBaseAsset(i)); + roundtripSwapActor = address(actor); + + // SWAP 1 + + uint256 actorInBalanceBefore = assetTSTIn.balanceOf(roundtripSwapActor); + + if (i % 2 == 0) { + // token0 -> token1 case + amount0In = amount; + amount1Out = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount0In); + } else { + // token1 -> token0 case + amount1In = amount; + amount0Out = maglev.quoteExactInput(address(assetTST2), address(assetTST), amount1In); } + + swap(amount0Out, amount1Out, amount1In, amount0In, 0); + + // SWAP 2 + + if (i % 2 == 0) { + // token0 -> token1 case + amount1In = amount1Out; + amount0Out = maglev.quoteExactInput(address(assetTST2), address(assetTST), amount1In); + } else { + // token1 -> token0 case + amount0In = amount0Out; + amount1Out = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount0In); + } + + swap(amount0Out, amount1Out, amount1In, amount0In, 0); + + uint256 actorInBalanceAfter = assetTSTIn.balanceOf(roundtripSwapActor); + + // HSPOST + assertLe(actorInBalanceAfter, actorInBalanceBefore, HSPOST_SWAP_B); } /////////////////////////////////////////////////////////////////////////////////////////////// - // HELPERS // + // HSPOST: SWAP // /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @notice Postconditions common to all three curves + function _commonPostconditions(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In) + internal + { + if (amount0Out > 0) { + assertEq( + defaultVarsBefore.users[receiver].assetTSTBalance, + defaultVarsBefore.users[receiver].assetTSTBalance + amount0Out - amount0In, + HSPOST_SWAP_C + ); + } + + if (amount1Out > 0) { + assertEq( + defaultVarsBefore.users[receiver].assetTST2Balance, + defaultVarsBefore.users[receiver].assetTST2Balance + amount1Out - amount1In, + HSPOST_SWAP_C + ); + } + assertGe(defaultVarsBefore.holderNAV, defaultVarsAfter.holderNAV, HSPOST_SWAP_A); + } + + /// @notice Postconditions for EulerSwap curve + function _eulerSwapPostconditions() internal { + // TODO Implement postconditions + } + + /// @notice Postconditions for ConstantProduct curve + function _constantProductPostconditions() internal { + // TODO Implement postconditions + } + + /// @notice ºPostconditions for ConstantSum curve + function _constantSumPostconditions() internal { + // TODO Implement postconditions + } } diff --git a/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol b/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol index bc7c6d0..4e37517 100644 --- a/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol +++ b/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol @@ -25,6 +25,8 @@ abstract contract DefaultBeforeAfterHooks is BaseHooks { } struct DefaultVars { + // Holder + int256 holderNAV; mapping(address => User) users; } @@ -51,14 +53,14 @@ abstract contract DefaultBeforeAfterHooks is BaseHooks { function _defaultHooksBefore() internal { // Default values - _setVaultValues(defaultVarsBefore); + _setDefaultValues(defaultVarsBefore); // Health & user account data _setUserValues(defaultVarsBefore); } function _defaultHooksAfter() internal { // Default values - _setVaultValues(defaultVarsAfter); + _setDefaultValues(defaultVarsAfter); // Health & user account data _setUserValues(defaultVarsAfter); } @@ -67,15 +69,22 @@ abstract contract DefaultBeforeAfterHooks is BaseHooks { // HELPERS // /////////////////////////////////////////////////////////////////////////////////////////////*/ - function _setVaultValues(DefaultVars storage _defaultVars) internal {} + function _setDefaultValues(DefaultVars storage _defaultVars) internal { + // Holder + _defaultVars.holderNAV = _getHolderNAV(); + } function _setUserValues(DefaultVars storage _defaultVars) internal { for (uint256 i; i < actorAddresses.length; i++) { - _setUserValuesPerActor(_defaultVars.users[actorAddresses[i]]); + address actorAddress_ = actorAddresses[i]; + _setUserValuesPerActor(_defaultVars.users[actorAddress_], actorAddress_); } } - function _setUserValuesPerActor(User storage _user) internal {} + function _setUserValuesPerActor(User storage _user, address _actorAddress) internal { + _user.assetTSTBalance = assetTST.balanceOf(_actorAddress); + _user.assetTST2Balance = assetTST2.balanceOf(_actorAddress); + } /////////////////////////////////////////////////////////////////////////////////////////////// // POST CONDITIONS: BASE // diff --git a/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol b/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol index 80df69f..037aec5 100644 --- a/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol +++ b/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol @@ -19,5 +19,7 @@ abstract contract BaseInvariants is HandlerAggregator { // BASE // /////////////////////////////////////////////////////////////////////////////////////////////// - function assert_INV_BASE_A() internal {} + function assert_INV_BASE_A() internal { + assertFalse(eTST.debtOf(holder) != 0 && eTST2.debtOf(holder) != 0, INV_BASE_A); + } } diff --git a/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol b/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol index 32bf19b..2e2666e 100644 --- a/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol +++ b/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol @@ -19,5 +19,5 @@ abstract contract InvariantsSpec { // BASE // /////////////////////////////////////////////////////////////////////////////////////////////// - string constant INV_BASE_A = "INV_BASE_A: performanceFee should be between bounds"; + string constant INV_BASE_A = "INV_BASE_A: At most one of vault0 or vault1 has debt (unless the CDP is under water)"; } diff --git a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol index 650bba3..b50d846 100644 --- a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol +++ b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol @@ -23,8 +23,12 @@ abstract contract PostconditionsSpec { /////////////////////////////////////////////////////////////////////////////////////////////*/ /////////////////////////////////////////////////////////////////////////////////////////////// - // BASE // + // SWAP // /////////////////////////////////////////////////////////////////////////////////////////////// - string constant GPOST_BASE_A = "GPOST_BASE_A: lastHarvestTimestamp increases monotonically"; + string constant HSPOST_SWAP_A = "HSPOST_SWAP_A: Holder's NAV should increase monotonically"; + + string constant HSPOST_SWAP_B = "HSPOST_SWAP_B: Swapping back and forth does not lead to a profit"; + + string constant HSPOST_SWAP_C = "HSPOST_SWAP_C: User should receive the amount out specified after a swap"; } From aa9d3059eb3bf401ba5cc054d95e969f42bfd228 Mon Sep 17 00:00:00 2001 From: Elpacos Date: Fri, 27 Dec 2024 11:48:41 +0100 Subject: [PATCH 03/18] fix: set initial suite deposits --- test/enigma-dark-invariants/CryticToFoundry.t.sol | 7 ++++++- test/enigma-dark-invariants/Setup.t.sol | 9 +++++++-- test/enigma-dark-invariants/base/BaseTest.t.sol | 2 +- .../handlers/swap/MaglevHandler.t.sol | 13 +++++++------ 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/test/enigma-dark-invariants/CryticToFoundry.t.sol b/test/enigma-dark-invariants/CryticToFoundry.t.sol index 63b4545..12a2922 100644 --- a/test/enigma-dark-invariants/CryticToFoundry.t.sol +++ b/test/enigma-dark-invariants/CryticToFoundry.t.sol @@ -41,13 +41,18 @@ contract CryticToFoundry is Invariants, Setup { function test_replaySwap() public { Tester.mint(2000000, 0, 0); - Tester.swap(1, 0, 0, 0, 0);//@audit-issue is possible to extract value from the protocol 1 wei of value + Tester.swap(1, 0, 0, 0, 0); //@audit-issue is possible to extract value from the protocol 1 wei of value } /////////////////////////////////////////////////////////////////////////////////////////////// // POSTCONDITIONS REPLAY // /////////////////////////////////////////////////////////////////////////////////////////////// + function test_replay_swap() public { + Tester.deposit(2000 ether, 0, 0); + Tester.swap(2 ether, 0, 0, 10 ether, 0); + } + /////////////////////////////////////////////////////////////////////////////////////////////// // INVARIANTS REPLAY // /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/Setup.t.sol b/test/enigma-dark-invariants/Setup.t.sol index 5e95556..d9be480 100644 --- a/test/enigma-dark-invariants/Setup.t.sol +++ b/test/enigma-dark-invariants/Setup.t.sol @@ -137,6 +137,11 @@ contract Setup is BaseTest { // Setup maglev lp as the first actor holder = address(actors[USER1]); + vm.prank(holder); + eTST.deposit(50e18, holder); + vm.prank(holder); + eTST2.deposit(50e18, holder); + /// @dev store the curve selected curve = _curveType; @@ -146,8 +151,8 @@ contract Setup is BaseTest { vault0: address(eTST), vault1: address(eTST2), myAccount: holder, - debtLimit0: 50e18, // TODO tweak these numbers - debtLimit1: 50e18, + debtLimit0: 500e18, // TODO tweak these numbers + debtLimit1: 500e18, fee: 0 }); diff --git a/test/enigma-dark-invariants/base/BaseTest.t.sol b/test/enigma-dark-invariants/base/BaseTest.t.sol index 0c1b41e..f4c775e 100644 --- a/test/enigma-dark-invariants/base/BaseTest.t.sol +++ b/test/enigma-dark-invariants/base/BaseTest.t.sol @@ -115,7 +115,7 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU // MAGLEV SPECIFIC HELPERS // /////////////////////////////////////////////////////////////////////////////////////////////// - function _getHolderNAV() public view returns (int256) { + function _getHolderNAV() internal view returns (int256) { uint256 balance0 = eTST.convertToAssets(eTST.balanceOf(holder)); uint256 debt0 = eTST.debtOf(holder); uint256 balance1 = eTST2.convertToAssets(eTST2.balanceOf(holder)); diff --git a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol index 001bb94..9c21660 100644 --- a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol @@ -35,7 +35,7 @@ abstract contract MaglevHandler is BaseHandler { address target = address(maglev); - require(amount0Out > 1 || amount1Out > 1, "MaglevHandler: Invalid amount out"); + require(amount0Out > 1 ether || amount1Out > 1 ether, "MaglevHandler: Invalid amount out"); if (amount0In > 0) { _transferByActor(address(assetTST), address(maglev), amount0In); @@ -49,8 +49,6 @@ abstract contract MaglevHandler is BaseHandler { (success, returnData) = actor.proxy(target, abi.encodeWithSelector(IMaglevBase.swap.selector, amount0Out, amount1Out, receiver, "")); - delete receiver; - if (roundtripSwapActor != address(0)) require(success); if (success) { @@ -68,9 +66,12 @@ abstract contract MaglevHandler is BaseHandler { assert(false); } + + delete receiver; } - function roundtripSwap(uint256 amount, uint8 i) external setup { + function roundtripSwap(uint256 amount, uint8 i) internal setup { + // TODO study this case uint256 amount0Out; uint256 amount1Out; uint256 amount0In; @@ -125,7 +126,7 @@ abstract contract MaglevHandler is BaseHandler { { if (amount0Out > 0) { assertEq( - defaultVarsBefore.users[receiver].assetTSTBalance, + defaultVarsAfter.users[receiver].assetTSTBalance, defaultVarsBefore.users[receiver].assetTSTBalance + amount0Out - amount0In, HSPOST_SWAP_C ); @@ -133,7 +134,7 @@ abstract contract MaglevHandler is BaseHandler { if (amount1Out > 0) { assertEq( - defaultVarsBefore.users[receiver].assetTST2Balance, + defaultVarsAfter.users[receiver].assetTST2Balance, defaultVarsBefore.users[receiver].assetTST2Balance + amount1Out - amount1In, HSPOST_SWAP_C ); From bc0eb87f7e5a5fbabdbf07b8f2cf6dfdc5e3b7bd Mon Sep 17 00:00:00 2001 From: Elpacos Date: Mon, 30 Dec 2024 10:32:12 +0100 Subject: [PATCH 04/18] chore: add reserves postconditions --- .../CryticToFoundry.t.sol | 4 +- .../base/BaseTest.t.sol | 3 +- .../handlers/swap/MaglevHandler.t.sol | 54 +++++++++++++++++- .../hooks/DefaultBeforeAfterHooks.t.sol | 8 +++ .../specs/PostconditionsSpec.t.sol | 12 ++++ .../utils/CoverageChecker.sol | 57 +++++++++++++++++++ 6 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 test/enigma-dark-invariants/utils/CoverageChecker.sol diff --git a/test/enigma-dark-invariants/CryticToFoundry.t.sol b/test/enigma-dark-invariants/CryticToFoundry.t.sol index 12a2922..fc715a5 100644 --- a/test/enigma-dark-invariants/CryticToFoundry.t.sol +++ b/test/enigma-dark-invariants/CryticToFoundry.t.sol @@ -49,8 +49,8 @@ contract CryticToFoundry is Invariants, Setup { /////////////////////////////////////////////////////////////////////////////////////////////// function test_replay_swap() public { - Tester.deposit(2000 ether, 0, 0); - Tester.swap(2 ether, 0, 0, 10 ether, 0); + Tester.setPrice(1, 1); + Tester.swap(0, 0, 0, 1000313385499984830, 0); } /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/base/BaseTest.t.sol b/test/enigma-dark-invariants/base/BaseTest.t.sol index f4c775e..22b2a60 100644 --- a/test/enigma-dark-invariants/base/BaseTest.t.sol +++ b/test/enigma-dark-invariants/base/BaseTest.t.sol @@ -12,6 +12,7 @@ import {StdUtils} from "forge-std/StdUtils.sol"; import {Actor} from "../utils/Actor.sol"; import {PropertiesConstants} from "../utils/PropertiesConstants.sol"; import {StdAsserts} from "../utils/StdAsserts.sol"; +import {CoverageChecker} from "../utils/CoverageChecker.sol"; // Base import {BaseStorage} from "./BaseStorage.t.sol"; @@ -21,7 +22,7 @@ import "forge-std/console.sol"; /// @notice Base contract for all test contracts extends BaseStorage /// @dev Provides setup modifier and cheat code setup /// @dev inherits Storage, Testing constants assertions and utils needed for testing -abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdUtils { +abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdUtils, CoverageChecker { bool internal IS_TEST = true; /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol index 9c21660..c138156 100644 --- a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol @@ -35,7 +35,9 @@ abstract contract MaglevHandler is BaseHandler { address target = address(maglev); - require(amount0Out > 1 ether || amount1Out > 1 ether, "MaglevHandler: Invalid amount out"); + //if (amount0Out >= 2 ether && amount1In >= 10 ether) assert(false); + + //require(amount0Out > 1 ether || amount1Out > 1 ether, "MaglevHandler: Invalid amount out"); if (amount0In > 0) { _transferByActor(address(assetTST), address(maglev), amount0In); @@ -64,7 +66,9 @@ abstract contract MaglevHandler is BaseHandler { _constantSumPostconditions(); } - assert(false); + //assert((amount0Out > 1 && amount1In > 1) || (amount1Out > 1 && amount0In > 1)); + + _checkCoverage(amount0Out, 0, type(uint256).max); } delete receiver; @@ -124,6 +128,8 @@ abstract contract MaglevHandler is BaseHandler { function _commonPostconditions(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In) internal { + /// @dev HSPOST_SWAP_A + if (amount0Out > 0) { assertEq( defaultVarsAfter.users[receiver].assetTSTBalance, @@ -139,7 +145,49 @@ abstract contract MaglevHandler is BaseHandler { HSPOST_SWAP_C ); } - assertGe(defaultVarsBefore.holderNAV, defaultVarsAfter.holderNAV, HSPOST_SWAP_A); + assertGe(defaultVarsAfter.holderNAV, defaultVarsBefore.holderNAV, HSPOST_SWAP_A); + + /// @dev HSPOST_RESERVES_A + + if (amount0In < defaultVarsBefore.holderETSTDebt) { + assertEq(defaultVarsAfter.holderETSTDebt, defaultVarsBefore.holderETSTDebt - amount0In, HSPOST_SWAP_B); + } else { + assertEq(defaultVarsAfter.holderETSTDebt, 0, HSPOST_RESERVES_A); + } + + if (amount1In < defaultVarsBefore.holderETST2Debt) { + assertEq(defaultVarsAfter.holderETST2Debt, defaultVarsBefore.holderETST2Debt - amount1In, HSPOST_SWAP_B); + } else { + assertEq(defaultVarsAfter.holderETST2Debt, 0, HSPOST_RESERVES_A); + } + + /// @dev HSPOST_RESERVES_B + + if (amount0Out < defaultVarsBefore.holderETSTAssets) { + assertEq( + defaultVarsAfter.holderETSTAssets, + defaultVarsBefore.holderETSTAssets - amount0Out + amount0In, + HSPOST_RESERVES_B + ); + } else { + assertEq(defaultVarsAfter.holderETSTAssets, 0, HSPOST_RESERVES_B); + assertEq( + defaultVarsAfter.holderETSTDebt, amount0Out - defaultVarsBefore.holderETSTAssets, HSPOST_RESERVES_C + ); + } + + if (amount1Out < defaultVarsBefore.holderETST2Assets) { + assertEq( + defaultVarsAfter.holderETST2Assets, + defaultVarsBefore.holderETST2Assets - amount1Out + amount1In, + HSPOST_RESERVES_B + ); + } else { + assertEq(defaultVarsAfter.holderETST2Assets, 0, HSPOST_RESERVES_B); + assertEq( + defaultVarsAfter.holderETST2Debt, amount1Out - defaultVarsBefore.holderETST2Assets, HSPOST_RESERVES_C + ); + } } /// @notice Postconditions for EulerSwap curve diff --git a/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol b/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol index 4e37517..ab7ac4d 100644 --- a/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol +++ b/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol @@ -27,6 +27,10 @@ abstract contract DefaultBeforeAfterHooks is BaseHooks { struct DefaultVars { // Holder int256 holderNAV; + uint256 holderETSTAssets; + uint256 holderETST2Assets; + uint256 holderETSTDebt; + uint256 holderETST2Debt; mapping(address => User) users; } @@ -72,6 +76,10 @@ abstract contract DefaultBeforeAfterHooks is BaseHooks { function _setDefaultValues(DefaultVars storage _defaultVars) internal { // Holder _defaultVars.holderNAV = _getHolderNAV(); + _defaultVars.holderETSTAssets = eTST.convertToAssets(eTST.balanceOf(holder)); + _defaultVars.holderETST2Assets = eTST2.convertToAssets(eTST2.balanceOf(holder)); + _defaultVars.holderETSTDebt = eTST.debtOf(holder); + _defaultVars.holderETST2Debt = eTST2.debtOf(holder); } function _setUserValues(DefaultVars storage _defaultVars) internal { diff --git a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol index b50d846..456610f 100644 --- a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol +++ b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol @@ -31,4 +31,16 @@ abstract contract PostconditionsSpec { string constant HSPOST_SWAP_B = "HSPOST_SWAP_B: Swapping back and forth does not lead to a profit"; string constant HSPOST_SWAP_C = "HSPOST_SWAP_C: User should receive the amount out specified after a swap"; + + /////////////////////////////////////////////////////////////////////////////////////////////// + // RESERVES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + string constant HSPOST_RESERVES_A = "HSPOST_RESERVES_A: If there is debt in tokenIn, the debt must be repaid"; + + string constant HSPOST_RESERVES_B = + "HSPOST_RESERVES_B: If amountOut does not exceed tokenOut collateral, tokenOut amount is withdrawn"; + + string constant HSPOST_RESERVES_C = + "HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed"; } diff --git a/test/enigma-dark-invariants/utils/CoverageChecker.sol b/test/enigma-dark-invariants/utils/CoverageChecker.sol new file mode 100644 index 0000000..0c46295 --- /dev/null +++ b/test/enigma-dark-invariants/utils/CoverageChecker.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +abstract contract CoverageChecker { + function _checkCoverage(uint256 coverage, uint256 low, uint256 high) internal pure returns (string memory) { + // Validate the range + require(high > low, "High must be greater than Low."); + require(coverage >= low && coverage <= high, "Coverage must be within the provided range."); + + // Calculate the size of each threshold interval + uint256 range = high - low; + uint256 step = range / 20; // Divide the range into 20 thresholds + + // Check which threshold the coverage falls into + if (coverage <= low + step) { + return "Threshold 1: Very Low Coverage"; + } else if (coverage <= low + step * 2) { + return "Threshold 2: Critical Low Coverage"; + } else if (coverage <= low + step * 3) { + return "Threshold 3: Low Coverage"; + } else if (coverage <= low + step * 4) { + return "Threshold 4: Below Average Coverage"; + } else if (coverage <= low + step * 5) { + return "Threshold 5: Near Average Coverage"; + } else if (coverage <= low + step * 6) { + return "Threshold 6: Average Coverage"; + } else if (coverage <= low + step * 7) { + return "Threshold 7: Slightly Above Average"; + } else if (coverage <= low + step * 8) { + return "Threshold 8: Moderate Coverage"; + } else if (coverage <= low + step * 9) { + return "Threshold 9: Good Coverage"; + } else if (coverage <= low + step * 10) { + return "Threshold 10: Very Good Coverage"; + } else if (coverage <= low + step * 11) { + return "Threshold 11: Excellent Coverage"; + } else if (coverage <= low + step * 12) { + return "Threshold 12: Strong Coverage"; + } else if (coverage <= low + step * 13) { + return "Threshold 13: High Coverage"; + } else if (coverage <= low + step * 14) { + return "Threshold 14: Very High Coverage"; + } else if (coverage <= low + step * 15) { + return "Threshold 15: Outstanding Coverage"; + } else if (coverage <= low + step * 16) { + return "Threshold 16: Exceptional Coverage"; + } else if (coverage <= low + step * 17) { + return "Threshold 17: Nearly Perfect Coverage"; + } else if (coverage <= low + step * 18) { + return "Threshold 18: Almost Full Coverage"; + } else if (coverage <= low + step * 19) { + return "Threshold 19: Near Maximum Coverage"; + } else { + return "Threshold 20: Maximum Coverage Achieved!"; + } + } +} From be01ce2f682339a9df472ea325eb0aec22c3e652 Mon Sep 17 00:00:00 2001 From: Elpacos Date: Wed, 1 Jan 2025 13:21:50 +0100 Subject: [PATCH 05/18] chore: add quoting to handlers --- .../CryticToFoundry.t.sol | 31 ++++++++--- test/enigma-dark-invariants/Setup.t.sol | 2 + test/enigma-dark-invariants/Tester.t.sol | 2 + .../base/BaseHandler.t.sol | 4 ++ .../base/BaseTest.t.sol | 2 - .../simulators/DonationAttackHandler.t.sol | 6 +-- .../handlers/swap/MaglevHandler.t.sol | 54 +++++++++++++------ .../hooks/DefaultBeforeAfterHooks.t.sol | 7 ++- .../specs/NonRevertPropertiesSpec.t.sol | 4 +- 9 files changed, 81 insertions(+), 31 deletions(-) diff --git a/test/enigma-dark-invariants/CryticToFoundry.t.sol b/test/enigma-dark-invariants/CryticToFoundry.t.sol index fc715a5..bb34f8b 100644 --- a/test/enigma-dark-invariants/CryticToFoundry.t.sol +++ b/test/enigma-dark-invariants/CryticToFoundry.t.sol @@ -14,6 +14,8 @@ import {Setup} from "./Setup.t.sol"; * The objective is to go from random values to hardcoded values that can be analyzed more easily */ contract CryticToFoundry is Invariants, Setup { + bool internal IS_TEST = true; + CryticToFoundry Tester = this; modifier setup() override { @@ -36,21 +38,34 @@ contract CryticToFoundry is Invariants, Setup { vm.warp(101007); } - /// @dev Needed in order for foundry to recognise the contract as a test, faster debugging - function testAux() public {} + /////////////////////////////////////////////////////////////////////////////////////////////// + // POSTCONDITIONS REPLAY // + /////////////////////////////////////////////////////////////////////////////////////////////// function test_replaySwap() public { Tester.mint(2000000, 0, 0); Tester.swap(1, 0, 0, 0, 0); //@audit-issue is possible to extract value from the protocol 1 wei of value } - /////////////////////////////////////////////////////////////////////////////////////////////// - // POSTCONDITIONS REPLAY // - /////////////////////////////////////////////////////////////////////////////////////////////// - function test_replay_swap() public { - Tester.setPrice(1, 1); - Tester.swap(0, 0, 0, 1000313385499984830, 0); + Tester.swap(0, 1, 0, 0, 0); //@audit-issue is possible to extract value from the protocol 1 wei of value -> rounding down on fx and fy functions fx(y) == fx(y-1) -> HSPOST_SWAP_A + } + + function test_replay_nav() public { + //@audit-issue when price changes user lp looses nav after a trade + Tester.setPrice(1, 0.1 ether); + Tester.swap(10, 0, 0, 10, 0); + } + + function test_replay_roundtripswap() public { + Tester.donateUnderlying(300000000000, 0); + Tester.roundtripSwap(100000000, 0); // @audit-issue user receives the amount donated -> HSPOST_SWAP_B + } + + function test_replay_swap_roundtripswap() public { + //@audit-issue user gets 1 wei more one the swap back -> HSPOST_SWAP_B + Tester.swap(15167520363383348756138763841789458381, 16455119106352766170018672268887607023990, 2, 0, 0); + Tester.roundtripSwap(200000000, 0); } /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/Setup.t.sol b/test/enigma-dark-invariants/Setup.t.sol index d9be480..ff87f57 100644 --- a/test/enigma-dark-invariants/Setup.t.sol +++ b/test/enigma-dark-invariants/Setup.t.sol @@ -106,9 +106,11 @@ contract Setup is BaseTest { // Deploy base assets assetTST = new TestERC20("Test Token", "TST", 18); baseAssets.push(address(assetTST)); + oracle.setPrice(address(assetTST), unitOfAccount, 1e18); assetTST2 = new TestERC20("Test Token 2", "TST2", 18); baseAssets.push(address(assetTST2)); + oracle.setPrice(address(assetTST2), unitOfAccount, 1e18); // Deploy the vaults eTST = _deployEVault(address(assetTST)); diff --git a/test/enigma-dark-invariants/Tester.t.sol b/test/enigma-dark-invariants/Tester.t.sol index 8a9a394..3d55b29 100644 --- a/test/enigma-dark-invariants/Tester.t.sol +++ b/test/enigma-dark-invariants/Tester.t.sol @@ -8,6 +8,8 @@ import {Setup} from "./Setup.t.sol"; /// @notice Entry point for invariant testing, inherits all contracts, invariants & handler /// @dev Mono contract that contains all the testing logic contract Tester is Invariants, Setup { + bool internal IS_TEST = true; + constructor() payable { // Deploy protocol contracts and protocol actors setUp(); diff --git a/test/enigma-dark-invariants/base/BaseHandler.t.sol b/test/enigma-dark-invariants/base/BaseHandler.t.sol index f20e1f8..882f92a 100644 --- a/test/enigma-dark-invariants/base/BaseHandler.t.sol +++ b/test/enigma-dark-invariants/base/BaseHandler.t.sol @@ -55,6 +55,10 @@ contract BaseHandler is HookAggregator { return vaults[_vaultIndex]; } + function _getAssetsByDir(bool dir) internal view returns (address assetIn, address assetOut) { + return dir ? (address(assetTST), address(assetTST2)) : (address(assetTST2), address(assetTST)); + } + /////////////////////////////////////////////////////////////////////////////////////////////// // HELPERS // /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/base/BaseTest.t.sol b/test/enigma-dark-invariants/base/BaseTest.t.sol index 22b2a60..b613943 100644 --- a/test/enigma-dark-invariants/base/BaseTest.t.sol +++ b/test/enigma-dark-invariants/base/BaseTest.t.sol @@ -23,8 +23,6 @@ import "forge-std/console.sol"; /// @dev Provides setup modifier and cheat code setup /// @dev inherits Storage, Testing constants assertions and utils needed for testing abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdUtils, CoverageChecker { - bool internal IS_TEST = true; - /////////////////////////////////////////////////////////////////////////////////////////////// // ACTOR PROXY MECHANISM // /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol index 12dde69..7df2597 100644 --- a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol @@ -26,14 +26,14 @@ contract DonationAttackHandler is BaseHandler { /// @notice This function transfers any amount of assets to a contract in the system simulating /// a big range of donation attacks - function donateUnderlying(uint256 amount, uint8 i) external { - TestERC20 _token = TestERC20(_getRandomBaseAsset(i)); + function donateUnderlying(uint256 amount, uint8 i) external {// TODO remove comments when fixed +/* TestERC20 _token = TestERC20(_getRandomBaseAsset(i)); address target = address(maglev); _token.mint(address(this), amount); - _token.transfer(target, amount); + _token.transfer(target, amount); */ } /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol index c138156..22cb658 100644 --- a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol @@ -27,6 +27,10 @@ abstract contract MaglevHandler is BaseHandler { /////////////////////////////////////////////////////////////////////////////////////////////// function swap(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In, uint8 i) public setup { + console.log("amount0Out: %s", amount0Out); + console.log("amount1Out: %s", amount1Out); + console.log("amount0In: %s", amount0In); + console.log("amount1In: %s", amount1In); bool success; bytes memory returnData; @@ -74,8 +78,7 @@ abstract contract MaglevHandler is BaseHandler { delete receiver; } - function roundtripSwap(uint256 amount, uint8 i) internal setup { - // TODO study this case + function roundtripSwap(uint256 amount, uint8 i) external setup { uint256 amount0Out; uint256 amount1Out; uint256 amount0In; @@ -98,7 +101,7 @@ abstract contract MaglevHandler is BaseHandler { amount0Out = maglev.quoteExactInput(address(assetTST2), address(assetTST), amount1In); } - swap(amount0Out, amount1Out, amount1In, amount0In, 0); + swap(amount0Out, amount1Out, amount0In, amount1In, 0); // SWAP 2 @@ -106,18 +109,42 @@ abstract contract MaglevHandler is BaseHandler { // token0 -> token1 case amount1In = amount1Out; amount0Out = maglev.quoteExactInput(address(assetTST2), address(assetTST), amount1In); + delete amount1Out; // @audit seems like input amounts are kinda delayed check uniswap v2 + delete amount0In; } else { // token1 -> token0 case amount0In = amount0Out; amount1Out = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount0In); + delete amount0Out; + delete amount1In; } - swap(amount0Out, amount1Out, amount1In, amount0In, 0); + swap(amount0Out, amount1Out, amount0In, amount1In, 0); uint256 actorInBalanceAfter = assetTSTIn.balanceOf(roundtripSwapActor); // HSPOST - assertLe(actorInBalanceAfter, actorInBalanceBefore, HSPOST_SWAP_B); + //assertLe(actorInBalanceAfter, actorInBalanceBefore, HSPOST_SWAP_B); + } + + function quoteExactInput(uint256 amountIn, bool dir) external { + (address assetIn, address assetOut) = _getAssetsByDir(dir); + + try maglev.quoteExactInput(assetIn, assetOut, amountIn) returns (uint256 amountOut) {} + catch Error(string memory) { + // HSPOST + assertTrue(false, NR_QUOTE_A); + } + } + + function quoteExactOutput(uint256 amountIn, bool dir) external { + (address assetIn, address assetOut) = _getAssetsByDir(dir); + + try maglev.quoteExactOutput(assetIn, assetOut, amountIn) returns (uint256 amountOut) {} + catch Error(string memory) { + // HSPOST + assertTrue(false, NR_QUOTE_B); + } } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -128,12 +155,12 @@ abstract contract MaglevHandler is BaseHandler { function _commonPostconditions(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In) internal { - /// @dev HSPOST_SWAP_A + /// @dev HSPOST_SWAP_C if (amount0Out > 0) { assertEq( defaultVarsAfter.users[receiver].assetTSTBalance, - defaultVarsBefore.users[receiver].assetTSTBalance + amount0Out - amount0In, + defaultVarsBefore.users[receiver].assetTSTBalance + amount0Out, HSPOST_SWAP_C ); } @@ -141,11 +168,12 @@ abstract contract MaglevHandler is BaseHandler { if (amount1Out > 0) { assertEq( defaultVarsAfter.users[receiver].assetTST2Balance, - defaultVarsBefore.users[receiver].assetTST2Balance + amount1Out - amount1In, + defaultVarsBefore.users[receiver].assetTST2Balance + amount1Out, HSPOST_SWAP_C ); } - assertGe(defaultVarsAfter.holderNAV, defaultVarsBefore.holderNAV, HSPOST_SWAP_A); + + //assertGe(defaultVarsAfter.holderNAV, defaultVarsBefore.holderNAV, HSPOST_SWAP_A);// TODO remove + 1 when rounding is fixed /// @dev HSPOST_RESERVES_A @@ -165,9 +193,7 @@ abstract contract MaglevHandler is BaseHandler { if (amount0Out < defaultVarsBefore.holderETSTAssets) { assertEq( - defaultVarsAfter.holderETSTAssets, - defaultVarsBefore.holderETSTAssets - amount0Out + amount0In, - HSPOST_RESERVES_B + defaultVarsAfter.holderETSTAssets, defaultVarsBefore.holderETSTAssets - amount0Out, HSPOST_RESERVES_B ); } else { assertEq(defaultVarsAfter.holderETSTAssets, 0, HSPOST_RESERVES_B); @@ -178,9 +204,7 @@ abstract contract MaglevHandler is BaseHandler { if (amount1Out < defaultVarsBefore.holderETST2Assets) { assertEq( - defaultVarsAfter.holderETST2Assets, - defaultVarsBefore.holderETST2Assets - amount1Out + amount1In, - HSPOST_RESERVES_B + defaultVarsAfter.holderETST2Assets, defaultVarsBefore.holderETST2Assets - amount1Out, HSPOST_RESERVES_B ); } else { assertEq(defaultVarsAfter.holderETST2Assets, 0, HSPOST_RESERVES_B); diff --git a/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol b/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol index ab7ac4d..5042d0e 100644 --- a/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol +++ b/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol @@ -76,8 +76,11 @@ abstract contract DefaultBeforeAfterHooks is BaseHooks { function _setDefaultValues(DefaultVars storage _defaultVars) internal { // Holder _defaultVars.holderNAV = _getHolderNAV(); - _defaultVars.holderETSTAssets = eTST.convertToAssets(eTST.balanceOf(holder)); - _defaultVars.holderETST2Assets = eTST2.convertToAssets(eTST2.balanceOf(holder)); + _defaultVars.holderETSTAssets = + eTST.convertToAssets(eTST.balanceOf(holder)) + assetTST.balanceOf(address(maglev)); + /// @dev adding maglev balance to take donations into account + _defaultVars.holderETST2Assets = + eTST2.convertToAssets(eTST2.balanceOf(holder)) + assetTST2.balanceOf(address(maglev)); _defaultVars.holderETSTDebt = eTST.debtOf(holder); _defaultVars.holderETST2Debt = eTST2.debtOf(holder); } diff --git a/test/enigma-dark-invariants/specs/NonRevertPropertiesSpec.t.sol b/test/enigma-dark-invariants/specs/NonRevertPropertiesSpec.t.sol index 71bef7a..781ad45 100644 --- a/test/enigma-dark-invariants/specs/NonRevertPropertiesSpec.t.sol +++ b/test/enigma-dark-invariants/specs/NonRevertPropertiesSpec.t.sol @@ -19,5 +19,7 @@ abstract contract NonRevertPropertiesSpec { // BASE // /////////////////////////////////////////////////////////////////////////////////////////////// - string constant NR_BASE_A = "NR_BASE_A: updateInterestAccrued should not revert"; + string constant NR_QUOTE_A = "NR_QUOTE_A: quoteExactInput should not revert"; + + string constant NR_QUOTE_B = "NR_QUOTE_B: quoteExactOutput should not revert"; } From 99fa4212b3848bd81d5f9f3d1a992c2c9e1a71cf Mon Sep 17 00:00:00 2001 From: Elpacos Date: Wed, 1 Jan 2025 13:24:53 +0100 Subject: [PATCH 06/18] fix: run formatter --- .../handlers/simulators/DonationAttackHandler.t.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol index 7df2597..47d861c 100644 --- a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol @@ -26,14 +26,15 @@ contract DonationAttackHandler is BaseHandler { /// @notice This function transfers any amount of assets to a contract in the system simulating /// a big range of donation attacks - function donateUnderlying(uint256 amount, uint8 i) external {// TODO remove comments when fixed -/* TestERC20 _token = TestERC20(_getRandomBaseAsset(i)); + function donateUnderlying(uint256 amount, uint8 i) external { + /* TestERC20 _token = TestERC20(_getRandomBaseAsset(i)); address target = address(maglev); _token.mint(address(this), amount); _token.transfer(target, amount); */ + // TODO remove comments when fixed } /////////////////////////////////////////////////////////////////////////////////////////////// From 774f19c25cb0748a486ee30c130705ab68076f32 Mon Sep 17 00:00:00 2001 From: Elpacos Date: Wed, 1 Jan 2025 13:27:08 +0100 Subject: [PATCH 07/18] fix: run formatter --- .../handlers/simulators/DonationAttackHandler.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol index 47d861c..99dd940 100644 --- a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol @@ -34,7 +34,7 @@ contract DonationAttackHandler is BaseHandler { _token.mint(address(this), amount); _token.transfer(target, amount); */ - // TODO remove comments when fixed + // TODO remove comments when fixed } /////////////////////////////////////////////////////////////////////////////////////////////// From ef38465207a802844bf7e6c70cde4dd8723e664f Mon Sep 17 00:00:00 2001 From: Elpacos Date: Wed, 1 Jan 2025 13:32:58 +0100 Subject: [PATCH 08/18] fix: build size error --- test/enigma-dark-invariants/CryticToFoundry.t.sol | 2 -- test/enigma-dark-invariants/Tester.t.sol | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/test/enigma-dark-invariants/CryticToFoundry.t.sol b/test/enigma-dark-invariants/CryticToFoundry.t.sol index bb34f8b..48bd513 100644 --- a/test/enigma-dark-invariants/CryticToFoundry.t.sol +++ b/test/enigma-dark-invariants/CryticToFoundry.t.sol @@ -14,8 +14,6 @@ import {Setup} from "./Setup.t.sol"; * The objective is to go from random values to hardcoded values that can be analyzed more easily */ contract CryticToFoundry is Invariants, Setup { - bool internal IS_TEST = true; - CryticToFoundry Tester = this; modifier setup() override { diff --git a/test/enigma-dark-invariants/Tester.t.sol b/test/enigma-dark-invariants/Tester.t.sol index 3d55b29..92fa058 100644 --- a/test/enigma-dark-invariants/Tester.t.sol +++ b/test/enigma-dark-invariants/Tester.t.sol @@ -8,7 +8,7 @@ import {Setup} from "./Setup.t.sol"; /// @notice Entry point for invariant testing, inherits all contracts, invariants & handler /// @dev Mono contract that contains all the testing logic contract Tester is Invariants, Setup { - bool internal IS_TEST = true; + bool public IS_TEST = true; constructor() payable { // Deploy protocol contracts and protocol actors From 9c252a1c3679cd0c6f59943a6c49f66a86eb44db Mon Sep 17 00:00:00 2001 From: Elpacos Date: Wed, 1 Jan 2025 13:34:49 +0100 Subject: [PATCH 09/18] fix: ci trigger branch --- .github/workflows/echidna-enigma-invariants.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/echidna-enigma-invariants.yml b/.github/workflows/echidna-enigma-invariants.yml index 11abd75..51b7909 100644 --- a/.github/workflows/echidna-enigma-invariants.yml +++ b/.github/workflows/echidna-enigma-invariants.yml @@ -3,7 +3,7 @@ name: Echidna Enigma Invariants on: push: branches: - - main + - master pull_request: env: @@ -26,7 +26,7 @@ jobs: uses: actions/checkout@v3 with: submodules: recursive - + - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: From 08ef7605b3d5143d48678aa1a6fcb209b51222f4 Mon Sep 17 00:00:00 2001 From: Elpacos Date: Wed, 1 Jan 2025 13:35:45 +0100 Subject: [PATCH 10/18] fix: ci trigger branch --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 762a296..8823a72 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,8 +2,9 @@ name: CI on: push: + branches: + - master pull_request: - workflow_dispatch: env: FOUNDRY_PROFILE: ci From af8d4a4928c206019ed588c6d525b777bfca76d6 Mon Sep 17 00:00:00 2001 From: Elpacos Date: Thu, 16 Jan 2025 13:33:16 +0100 Subject: [PATCH 11/18] chore: randomise maglev deployments --- Makefile | 5 ++ .../HandlerAggregator.t.sol | 2 + test/enigma-dark-invariants/Setup.t.sol | 88 +------------------ .../_config/echidna_config.yaml | 2 +- .../_config/echidna_config_runner.yaml | 57 ++++++++++++ .../base/BaseHandler.t.sol | 14 +++ .../base/BaseTest.t.sol | 36 ++++++++ .../handlers/euler/EVCHandler.t.sol | 17 +++- .../handlers/setup/MaglevSetupHandler.t.sol | 81 +++++++++++++++++ .../simulators/DonationAttackHandler.t.sol | 2 +- .../simulators/PriceOracleHandler.t.sol | 2 +- .../handlers/standard/ERC20Handler.t.sol | 12 +-- .../handlers/standard/ERC4626Handler.t.sol | 8 ++ .../handlers/swap/MaglevHandler.t.sol | 10 +-- 14 files changed, 234 insertions(+), 102 deletions(-) create mode 100644 test/enigma-dark-invariants/_config/echidna_config_runner.yaml create mode 100644 test/enigma-dark-invariants/handlers/setup/MaglevSetupHandler.t.sol diff --git a/Makefile b/Makefile index 797fa2c..aa5b0e5 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,11 @@ echidna-assert: echidna-explore: echidna test/enigma-dark-invariants/Tester.t.sol --contract Tester --test-mode exploration --config ./test/enigma-dark-invariants/_config/echidna_config.yaml --corpus-dir ./test/enigma-dark-invariants/_corpus/echidna/default/_data/corpus +# Invariants +echidna-docker: + echidna test/enigma-dark-invariants/Tester.t.sol --contract Tester --config ./test/enigma-dark-invariants/_config/echidna_config_runner.yaml --corpus-dir ./test/enigma-dark-invariants/_corpus/echidna/default/_data/corpus + + # Medusa medusa: medusa fuzz --config ./medusa.json \ No newline at end of file diff --git a/test/enigma-dark-invariants/HandlerAggregator.t.sol b/test/enigma-dark-invariants/HandlerAggregator.t.sol index 5cf81af..001f0de 100644 --- a/test/enigma-dark-invariants/HandlerAggregator.t.sol +++ b/test/enigma-dark-invariants/HandlerAggregator.t.sol @@ -6,6 +6,7 @@ import {EVCHandler} from "./handlers/euler/EVCHandler.t.sol"; import {ERC20Handler} from "./handlers/standard/ERC20Handler.t.sol"; import {ERC4626Handler} from "./handlers/standard/ERC4626Handler.t.sol"; import {MaglevHandler} from "./handlers/swap/MaglevHandler.t.sol"; +import {MaglevSetupHandler} from "./handlers/setup/MaglevSetupHandler.t.sol"; // Simulator Handler contracts, import {DonationAttackHandler} from "./handlers/simulators/DonationAttackHandler.t.sol"; @@ -17,6 +18,7 @@ abstract contract HandlerAggregator is ERC20Handler, // Module handlers ERC4626Handler, MaglevHandler, + MaglevSetupHandler, DonationAttackHandler, // Simulator handlers PriceOracleHandler { diff --git a/test/enigma-dark-invariants/Setup.t.sol b/test/enigma-dark-invariants/Setup.t.sol index ff87f57..9959f35 100644 --- a/test/enigma-dark-invariants/Setup.t.sol +++ b/test/enigma-dark-invariants/Setup.t.sol @@ -15,10 +15,6 @@ import {SequenceRegistry} from "evk/SequenceRegistry/SequenceRegistry.sol"; import {Base} from "evk/EVault/shared/Base.sol"; import {Dispatch} from "evk/EVault/Dispatch.sol"; import {EVault} from "evk/EVault/EVault.sol"; -import {MaglevBase} from "src/MaglevBase.sol"; -import {MaglevConstantSum} from "src/MaglevConstantSum.sol"; -import {MaglevConstantProduct} from "src/MaglevConstantProduct.sol"; -import {MaglevEulerSwap} from "src/MaglevEulerSwap.sol"; // Modules import {Initialize} from "evk/EVault/modules/Initialize.sol"; @@ -34,7 +30,6 @@ import {MockBalanceTracker} from "evk/../test/mocks/MockBalanceTracker.sol"; // Interfaces import {IEVault} from "evk/EVault/IEVault.sol"; import {IRMTestDefault} from "evk-test/mocks/IRMTestDefault.sol"; -import {IMaglevBase} from "src/interfaces/IMaglevBase.sol"; // Test Contracts import {TestERC20} from "test/enigma-dark-invariants/utils/mocks/TestERC20.sol"; @@ -55,7 +50,7 @@ contract Setup is BaseTest { _setUpActors(); // Deploy and setup maglev - _deployMaglev(_curveType); + _setUpMaglev(_curveType); } /// @notice Deploy euler env contracts @@ -108,7 +103,7 @@ contract Setup is BaseTest { baseAssets.push(address(assetTST)); oracle.setPrice(address(assetTST), unitOfAccount, 1e18); - assetTST2 = new TestERC20("Test Token 2", "TST2", 18); + assetTST2 = new TestERC20("Test Token 2", "TST2", 18); // TODO change decimals baseAssets.push(address(assetTST2)); oracle.setPrice(address(assetTST2), unitOfAccount, 1e18); @@ -135,76 +130,9 @@ contract Setup is BaseTest { // MAGLEV // /////////////////////////////////////////////////////////////////////////////////////////////// - function _deployMaglev(Curve _curveType) internal { + function _setUpMaglev(Curve _curveType) internal { // Setup maglev lp as the first actor holder = address(actors[USER1]); - - vm.prank(holder); - eTST.deposit(50e18, holder); - vm.prank(holder); - eTST2.deposit(50e18, holder); - - /// @dev store the curve selected - curve = _curveType; - - // Setup the maglev params - MaglevBase.BaseParams memory baseParams = MaglevBase.BaseParams({ - evc: address(evc), - vault0: address(eTST), - vault1: address(eTST2), - myAccount: holder, - debtLimit0: 500e18, // TODO tweak these numbers - debtLimit1: 500e18, - fee: 0 - }); - - /// @dev Switch between the different curves - if (curve == Curve.EULER_SWAP) { - _deployMaglevEulerSwap(baseParams); - } else if (curve == Curve.PRODUCT) { - _deployMaglevConstantProduct(baseParams); - } else { - _deployMaglevConstantSum(baseParams); - } - - // Set maglev as operator for the lp and call configure - vm.prank(holder); - evc.setAccountOperator(holder, address(maglev), true); - maglev.configure(); - - // Setup actors token approvals to maglev - address[] memory contracts = new address[](1); - contracts[0] = address(maglev); - - _setupActorApprovals(baseAssets, contracts); - } - - function _deployMaglevEulerSwap(MaglevBase.BaseParams memory _baseParams) internal { - maglev = IMaglevBase( - address( - new MaglevEulerSwap( - _baseParams, - MaglevEulerSwap.EulerSwapParams({ - priceX: 1e18, - priceY: 1e18, - concentrationX: 0.4e18, - concentrationY: 0.85e18 - }) - ) - ) - ); - } - - function _deployMaglevConstantProduct(MaglevBase.BaseParams memory _baseParams) internal { - maglev = IMaglevBase(address(new MaglevConstantProduct(_baseParams))); - } - - function _deployMaglevConstantSum(MaglevBase.BaseParams memory _baseParams) internal { - maglev = IMaglevBase( - address( - new MaglevConstantSum(_baseParams, MaglevConstantSum.ConstantSumParams({priceX: 1e18, priceY: 1e18})) - ) - ); } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -257,14 +185,4 @@ contract Setup is BaseTest { assert(success); actorAddress = address(_actor); } - - function _setupActorApprovals(address[] memory tokens, address[] memory contracts_) internal { - for (uint256 i; i < actorAddresses.length; i++) { - for (uint256 j; j < tokens.length; j++) { - for (uint256 k; k < contracts_.length; k++) { - _approve(tokens[j], actorAddresses[i], contracts_[k], type(uint256).max); - } - } - } - } } diff --git a/test/enigma-dark-invariants/_config/echidna_config.yaml b/test/enigma-dark-invariants/_config/echidna_config.yaml index 1616117..8af47f5 100644 --- a/test/enigma-dark-invariants/_config/echidna_config.yaml +++ b/test/enigma-dark-invariants/_config/echidna_config.yaml @@ -37,7 +37,7 @@ stopOnFail: false coverage: true # list of file formats to save coverage reports in; default is all possible formats -coverageFormats: [ "lcov", "html" ] +coverageFormats: [ "txt", "html" ] #directory to save the corpus; by default is disabled corpusDir: "test/invariants/_corpus/echidna/default/_data/corpus" diff --git a/test/enigma-dark-invariants/_config/echidna_config_runner.yaml b/test/enigma-dark-invariants/_config/echidna_config_runner.yaml new file mode 100644 index 0000000..4c7c00f --- /dev/null +++ b/test/enigma-dark-invariants/_config/echidna_config_runner.yaml @@ -0,0 +1,57 @@ +#codeSize max code size for deployed contratcs (default 24576, per EIP-170) +codeSize: 224576 + +#whether ot not to use the multi-abi mode of testing +#it’s not working for us, see: https://github.com/crytic/echidna/issues/547 +#multi-abi: true + +#balanceAddr is default balance for addresses +balanceAddr: 0x1000000000000000000000000 +#balanceContract overrides balanceAddr for the contract address (2^128 = ~3e38) +balanceContract: 0x1000000000000000000000000000000000000000000000000 + +#testLimit is the number of test sequences to run +testLimit: 20000000 + +#seqLen defines how many transactions are in a test sequence +seqLen: 300 + +#shrinkLimit determines how much effort is spent shrinking failing sequences +shrinkLimit: 2500 + +#propMaxGas defines gas cost at which a property fails +propMaxGas: 1000000000 + +#testMaxGas is a gas limit; does not cause failure, but terminates sequence +testMaxGas: 1000000000 + +# list of methods to filter +#filterFunctions: ["openCdpExt"] +# by default, blacklist methods in filterFunctions +#filterBlacklist: false + +#stopOnFail makes echidna terminate as soon as any property fails and has been shrunk +stopOnFail: false + +#coverage controls coverage guided testing +coverage: true + +# list of file formats to save coverage reports in; default is all possible formats +coverageFormats: [ "txt", "html" ] + +#directory to save the corpus; by default is disabled +corpusDir: "test/invariants/_corpus/echidna/default/_data/corpus" +# constants for corpus mutations (for experimentation only) +#mutConsts: [100, 1, 1] + +#remappings +cryticArgs: [ "--ignore-compile", "--solc-remaps", "@crytic/properties/=lib/properties/ forge-std/=lib/forge-std/src/ ds-test/=lib/forge-std/lib/ds-test/src/ openzeppelin/=lib/openzeppelin-contracts/contracts/" ] + +# maximum value to send to payable functions +maxValue: 1e+23 # 100000 eth + +#quiet produces (much) less verbose output +quiet: false + +# concurrent workers +workers: 10 diff --git a/test/enigma-dark-invariants/base/BaseHandler.t.sol b/test/enigma-dark-invariants/base/BaseHandler.t.sol index 882f92a..62a986b 100644 --- a/test/enigma-dark-invariants/base/BaseHandler.t.sol +++ b/test/enigma-dark-invariants/base/BaseHandler.t.sol @@ -18,6 +18,20 @@ import {HookAggregator} from "../hooks/HookAggregator.t.sol"; contract BaseHandler is HookAggregator { using EnumerableSet for EnumerableSet.UintSet; + /////////////////////////////////////////////////////////////////////////////////////////////// + // MODIFIERS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + modifier maglevNotDeployed() { + if (address(maglev) != address(0)) revert("BaseHandler: Maglev already deployed on this trace"); + _; + } + + modifier maglevDeployed() { + if (address(maglev) == address(0)) revert("BaseHandler: Maglev has not been deployed on this trace"); + _; + } + /////////////////////////////////////////////////////////////////////////////////////////////// // SHARED VARAIBLES // /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/base/BaseTest.t.sol b/test/enigma-dark-invariants/base/BaseTest.t.sol index b613943..fe51b9b 100644 --- a/test/enigma-dark-invariants/base/BaseTest.t.sol +++ b/test/enigma-dark-invariants/base/BaseTest.t.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.19; // Interfaces import {IERC20} from "openzeppelin-contracts/interfaces/IERC20.sol"; +import {IMaglevBase} from "src/interfaces/IMaglevBase.sol"; // Libraries import {Vm} from "forge-std/Base.sol"; @@ -14,6 +15,12 @@ import {PropertiesConstants} from "../utils/PropertiesConstants.sol"; import {StdAsserts} from "../utils/StdAsserts.sol"; import {CoverageChecker} from "../utils/CoverageChecker.sol"; +// Contracts +import {MaglevBase} from "src/MaglevBase.sol"; +import {MaglevConstantSum} from "src/MaglevConstantSum.sol"; +import {MaglevConstantProduct} from "src/MaglevConstantProduct.sol"; +import {MaglevEulerSwap} from "src/MaglevEulerSwap.sol"; + // Base import {BaseStorage} from "./BaseStorage.t.sol"; @@ -110,6 +117,16 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU require(success, string(returnData)); } + function _setupActorApprovals(address[] memory tokens, address[] memory contracts_) internal { + for (uint256 i; i < actorAddresses.length; i++) { + for (uint256 j; j < tokens.length; j++) { + for (uint256 k; k < contracts_.length; k++) { + _approve(tokens[j], actorAddresses[i], contracts_[k], type(uint256).max); + } + } + } + } + /////////////////////////////////////////////////////////////////////////////////////////////// // MAGLEV SPECIFIC HELPERS // /////////////////////////////////////////////////////////////////////////////////////////////// @@ -127,4 +144,23 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU return int256(balValue) - int256(debtValue); } + + function _deployMaglevEulerSwap( + MaglevBase.BaseParams memory _baseParams, + MaglevEulerSwap.EulerSwapParams memory _eulerSwapParams + ) internal { + maglev = IMaglevBase(address(new MaglevEulerSwap(_baseParams, _eulerSwapParams))); + } + + function _deployMaglevConstantProduct(MaglevBase.BaseParams memory _baseParams) internal { + maglev = IMaglevBase(address(new MaglevConstantProduct(_baseParams))); + } + + function _deployMaglevConstantSum(MaglevBase.BaseParams memory _baseParams) internal { + maglev = IMaglevBase( + address( + new MaglevConstantSum(_baseParams, MaglevConstantSum.ConstantSumParams({priceX: 1e18, priceY: 1e18})) + ) + ); + } } diff --git a/test/enigma-dark-invariants/handlers/euler/EVCHandler.t.sol b/test/enigma-dark-invariants/handlers/euler/EVCHandler.t.sol index d201f5a..e979f4f 100644 --- a/test/enigma-dark-invariants/handlers/euler/EVCHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/euler/EVCHandler.t.sol @@ -41,6 +41,8 @@ abstract contract EVCHandler is BaseHandler { if (success) { _after(); + } else { + revert("EVCHandler: setAccountOperator failed"); } } @@ -63,6 +65,8 @@ abstract contract EVCHandler is BaseHandler { if (success) { _after(); + } else { + revert("EVCHandler: enableCollateral failed"); } } @@ -83,6 +87,8 @@ abstract contract EVCHandler is BaseHandler { if (success) { _after(); + } else { + revert("EVCHandler: disableCollateral failed"); } } @@ -101,6 +107,8 @@ abstract contract EVCHandler is BaseHandler { if (success) { _after(); + } else { + revert("EVCHandler: disableCollateral failed"); } } @@ -122,6 +130,8 @@ abstract contract EVCHandler is BaseHandler { if (success) { _after(); + } else { + revert("EVCHandler: enableController failed"); } } @@ -136,7 +146,12 @@ abstract contract EVCHandler is BaseHandler { (success, returnData) = actor.proxy( address(evc), abi.encodeWithSelector(EthereumVaultConnector.disableController.selector, account) ); - _after(); + + if (success) { + _after(); + } else { + revert("EVCHandler: disableControllerEVC failed"); + } } /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/handlers/setup/MaglevSetupHandler.t.sol b/test/enigma-dark-invariants/handlers/setup/MaglevSetupHandler.t.sol new file mode 100644 index 0000000..8158e79 --- /dev/null +++ b/test/enigma-dark-invariants/handlers/setup/MaglevSetupHandler.t.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Contracts +import {MaglevBase} from "src/MaglevBase.sol"; +import {MaglevEulerSwap} from "src/MaglevEulerSwap.sol"; + +// Libraries +import "forge-std/console.sol"; + +// Test Contracts +import {Actor} from "../../utils/Actor.sol"; +import {BaseHandler} from "../../base/BaseHandler.t.sol"; + +/// @title MaglevSetupHandler +/// @notice Handler test contract for a set of actions +abstract contract MaglevSetupHandler is BaseHandler { + /////////////////////////////////////////////////////////////////////////////////////////////// + // STATE VARIABLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // ACTIONS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function setupMaglev( + uint8 leverage, + uint112 initialAmount0, + uint112 initialAmount1, + uint256 fee, + Curve _curveType, + MaglevEulerSwap.EulerSwapParams memory eulerSwapParams + ) public maglevNotDeployed { + // Clamp leverage at x10 + leverage = uint8(clampBetween(leverage, 1, 10)); + + uint112 debtLimit0 = initialAmount0 * leverage; + uint112 debtLimit1 = initialAmount1 * leverage; + + // Clamp concentration between 0.1e18 and 1e18 + eulerSwapParams.priceX = clampBetween(eulerSwapParams.priceX, 0.1e18, 1e18); + eulerSwapParams.priceY = clampBetween(eulerSwapParams.priceY, 0.1e18, 1e18); + + // Deposit initial funds on the vaults as the holder + vm.prank(holder); + eTST.deposit(initialAmount0, holder); + vm.prank(holder); + eTST2.deposit(initialAmount1, holder); + + // Setup the maglev params + MaglevBase.BaseParams memory baseParams = MaglevBase.BaseParams({ + evc: address(evc), + vault0: address(eTST), + vault1: address(eTST2), + myAccount: holder, + debtLimit0: debtLimit0, + debtLimit1: debtLimit1, + fee: fee + }); + + /// Deploy the specific curve type maglev contract + if (_curveType == Curve.EULER_SWAP) { + _deployMaglevEulerSwap(baseParams, eulerSwapParams); + } else if (_curveType == Curve.PRODUCT) { + _deployMaglevConstantProduct(baseParams); + } else { + _deployMaglevConstantSum(baseParams); + } + + // Set maglev as operator for the lp and call configure + vm.prank(holder); + evc.setAccountOperator(holder, address(maglev), true); + maglev.configure(); + + // Setup actors token approvals to maglev + address[] memory contracts = new address[](1); + contracts[0] = address(maglev); + + _setupActorApprovals(baseAssets, contracts); + } +} diff --git a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol index 99dd940..7f1c08d 100644 --- a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol @@ -26,7 +26,7 @@ contract DonationAttackHandler is BaseHandler { /// @notice This function transfers any amount of assets to a contract in the system simulating /// a big range of donation attacks - function donateUnderlying(uint256 amount, uint8 i) external { + function donateUnderlying(uint256 amount, uint8 i) external maglevDeployed { /* TestERC20 _token = TestERC20(_getRandomBaseAsset(i)); address target = address(maglev); diff --git a/test/enigma-dark-invariants/handlers/simulators/PriceOracleHandler.t.sol b/test/enigma-dark-invariants/handlers/simulators/PriceOracleHandler.t.sol index a97a875..2776c09 100644 --- a/test/enigma-dark-invariants/handlers/simulators/PriceOracleHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/simulators/PriceOracleHandler.t.sol @@ -18,7 +18,7 @@ abstract contract PriceOracleHandler is BaseHandler { // ACTIONS // /////////////////////////////////////////////////////////////////////////////////////////////// - /// @notice This function simulates changes in the interest rate model + /// @notice This function simulates changes in asset price function setPrice(uint8 i, uint256 price) external { address baseAsset = _getRandomBaseAsset(i); diff --git a/test/enigma-dark-invariants/handlers/standard/ERC20Handler.t.sol b/test/enigma-dark-invariants/handlers/standard/ERC20Handler.t.sol index a3959d5..c155de1 100644 --- a/test/enigma-dark-invariants/handlers/standard/ERC20Handler.t.sol +++ b/test/enigma-dark-invariants/handlers/standard/ERC20Handler.t.sol @@ -37,8 +37,8 @@ abstract contract ERC20Handler is BaseHandler { if (success) { _after(); - - assert(true); + } else { + revert("ERC20Handler: approve failed"); } } @@ -57,8 +57,8 @@ abstract contract ERC20Handler is BaseHandler { if (success) { _after(); - - assert(true); + } else { + revert("ERC20Handler: transfer failed"); } } @@ -80,8 +80,8 @@ abstract contract ERC20Handler is BaseHandler { if (success) { _after(); - - assert(true); + } else { + revert("ERC20Handler: transferFrom failed"); } } diff --git a/test/enigma-dark-invariants/handlers/standard/ERC4626Handler.t.sol b/test/enigma-dark-invariants/handlers/standard/ERC4626Handler.t.sol index d51294d..cd1cde0 100644 --- a/test/enigma-dark-invariants/handlers/standard/ERC4626Handler.t.sol +++ b/test/enigma-dark-invariants/handlers/standard/ERC4626Handler.t.sol @@ -38,6 +38,8 @@ abstract contract ERC4626Handler is BaseHandler { if (success) { _after(); + } else { + revert("ERC4626Handler: deposit failed"); } } @@ -56,6 +58,8 @@ abstract contract ERC4626Handler is BaseHandler { if (success) { _after(); + } else { + revert("ERC4626Handler: mint failed"); } } @@ -75,6 +79,8 @@ abstract contract ERC4626Handler is BaseHandler { if (success) { _after(); + } else { + revert("ERC4626Handler: withdraw failed"); } } @@ -94,6 +100,8 @@ abstract contract ERC4626Handler is BaseHandler { if (success) { _after(); + } else { + revert("ERC4626Handler: redeem failed"); } } diff --git a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol index 22cb658..6c3d963 100644 --- a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol @@ -26,11 +26,7 @@ abstract contract MaglevHandler is BaseHandler { // ACTIONS // /////////////////////////////////////////////////////////////////////////////////////////////// - function swap(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In, uint8 i) public setup { - console.log("amount0Out: %s", amount0Out); - console.log("amount1Out: %s", amount1Out); - console.log("amount0In: %s", amount0In); - console.log("amount1In: %s", amount1In); + function swap(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In, uint8 i) public setup maglevDeployed { bool success; bytes memory returnData; @@ -55,8 +51,6 @@ abstract contract MaglevHandler is BaseHandler { (success, returnData) = actor.proxy(target, abi.encodeWithSelector(IMaglevBase.swap.selector, amount0Out, amount1Out, receiver, "")); - if (roundtripSwapActor != address(0)) require(success); - if (success) { _after(); @@ -73,6 +67,8 @@ abstract contract MaglevHandler is BaseHandler { //assert((amount0Out > 1 && amount1In > 1) || (amount1Out > 1 && amount0In > 1)); _checkCoverage(amount0Out, 0, type(uint256).max); + } else { + revert("MaglevHandler: swap failed"); } delete receiver; From b611415a44be110a6e82a5a2de8c1ab541029096 Mon Sep 17 00:00:00 2001 From: Elpacos Date: Thu, 16 Jan 2025 18:58:37 +0100 Subject: [PATCH 12/18] chore: improvements --- .../CryticToFoundry.t.sol | 21 +++++++++++-------- .../handlers/setup/MaglevSetupHandler.t.sol | 8 ++++++- .../simulators/DonationAttackHandler.t.sol | 15 ++++++++++--- .../handlers/standard/ERC4626Handler.t.sol | 11 ++++++++++ .../handlers/swap/MaglevHandler.t.sol | 20 +++++++++--------- .../specs/PostconditionsSpec.t.sol | 7 +++++++ 6 files changed, 59 insertions(+), 23 deletions(-) diff --git a/test/enigma-dark-invariants/CryticToFoundry.t.sol b/test/enigma-dark-invariants/CryticToFoundry.t.sol index 48bd513..1e530ff 100644 --- a/test/enigma-dark-invariants/CryticToFoundry.t.sol +++ b/test/enigma-dark-invariants/CryticToFoundry.t.sol @@ -6,6 +6,7 @@ import "forge-std/Test.sol"; import "forge-std/console.sol"; // Contracts +import {MaglevEulerSwap} from "src/MaglevEulerSwap.sol"; import {Invariants} from "./Invariants.t.sol"; import {Setup} from "./Setup.t.sol"; @@ -40,29 +41,31 @@ contract CryticToFoundry is Invariants, Setup { // POSTCONDITIONS REPLAY // /////////////////////////////////////////////////////////////////////////////////////////////// - function test_replaySwap() public { - Tester.mint(2000000, 0, 0); - Tester.swap(1, 0, 0, 0, 0); //@audit-issue is possible to extract value from the protocol 1 wei of value - } - function test_replay_swap() public { - Tester.swap(0, 1, 0, 0, 0); //@audit-issue is possible to extract value from the protocol 1 wei of value -> rounding down on fx and fy functions fx(y) == fx(y-1) -> HSPOST_SWAP_A + //@audit-issue is possible to extract value from the protocol 1 wei of value + Tester.setupMaglev(10, 50e18, 50e18, 0, Curve(0), MaglevEulerSwap.EulerSwapParams(1e18, 1e18, 0.4e18, 0.85e18)); + Tester.mint(2000000, 0, 0); + Tester.swap(1, 0, 0, 0, 0); } function test_replay_nav() public { //@audit-issue when price changes user lp looses nav after a trade + Tester.setupMaglev(10, 50e18, 50e18, 0, Curve(0), MaglevEulerSwap.EulerSwapParams(1e18, 1e18, 0.4e18, 0.85e18)); Tester.setPrice(1, 0.1 ether); Tester.swap(10, 0, 0, 10, 0); } function test_replay_roundtripswap() public { + // @audit-ok user receives the amount donated -> HSPOST_SWAP_B -> expected functionality + Tester.setupMaglev(10, 50e18, 50e18, 0, Curve(0), MaglevEulerSwap.EulerSwapParams(1e18, 1e18, 0.4e18, 0.85e18)); Tester.donateUnderlying(300000000000, 0); - Tester.roundtripSwap(100000000, 0); // @audit-issue user receives the amount donated -> HSPOST_SWAP_B + Tester.roundtripSwap(100000000, 0); } - function test_replay_swap_roundtripswap() public { + function test_replay_2roundtripswap() public { //@audit-issue user gets 1 wei more one the swap back -> HSPOST_SWAP_B - Tester.swap(15167520363383348756138763841789458381, 16455119106352766170018672268887607023990, 2, 0, 0); + Tester.setupMaglev(10, 50e18, 50e18, 0, Curve(0), MaglevEulerSwap.EulerSwapParams(1e18, 1e18, 0.4e18, 0.85e18)); + Tester.swap(1516752036338334875613876384, 1645511910635276617001867226888, 2, 0, 0); Tester.roundtripSwap(200000000, 0); } diff --git a/test/enigma-dark-invariants/handlers/setup/MaglevSetupHandler.t.sol b/test/enigma-dark-invariants/handlers/setup/MaglevSetupHandler.t.sol index 8158e79..bda5b81 100644 --- a/test/enigma-dark-invariants/handlers/setup/MaglevSetupHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/setup/MaglevSetupHandler.t.sol @@ -28,12 +28,16 @@ abstract contract MaglevSetupHandler is BaseHandler { uint112 initialAmount0, uint112 initialAmount1, uint256 fee, - Curve _curveType, + Curve, /*_curveType*/ MaglevEulerSwap.EulerSwapParams memory eulerSwapParams ) public maglevNotDeployed { // Clamp leverage at x10 leverage = uint8(clampBetween(leverage, 1, 10)); + // Clamp minimum amount at 1000 tokens + initialAmount0 = uint112(clampBetween(initialAmount0, 1000e18, type(uint112).max)); + initialAmount1 = uint112(clampBetween(initialAmount1, 1000e18, type(uint112).max)); + uint112 debtLimit0 = initialAmount0 * leverage; uint112 debtLimit1 = initialAmount1 * leverage; @@ -58,6 +62,8 @@ abstract contract MaglevSetupHandler is BaseHandler { fee: fee }); + Curve _curveType = Curve.EULER_SWAP; // TODO remove hardcoded curve type -> try other curves on different instances + /// Deploy the specific curve type maglev contract if (_curveType == Curve.EULER_SWAP) { _deployMaglevEulerSwap(baseParams, eulerSwapParams); diff --git a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol index 7f1c08d..f104845 100644 --- a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol @@ -27,14 +27,23 @@ contract DonationAttackHandler is BaseHandler { /// @notice This function transfers any amount of assets to a contract in the system simulating /// a big range of donation attacks function donateUnderlying(uint256 amount, uint8 i) external maglevDeployed { - /* TestERC20 _token = TestERC20(_getRandomBaseAsset(i)); + TestERC20 _token = TestERC20(_getRandomBaseAsset(i)); address target = address(maglev); _token.mint(address(this), amount); - _token.transfer(target, amount); */ - // TODO remove comments when fixed + _token.transfer(target, amount); + } + + function donateUnderlyingToVault(uint256 amount, uint8 i) external { + address target = _getRandomVault(i); + + TestERC20 _token = TestERC20(IEVault(_getRandomBaseAsset(i)).asset()); + + _token.mint(address(this), amount); + + _token.transfer(target, amount); } /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/handlers/standard/ERC4626Handler.t.sol b/test/enigma-dark-invariants/handlers/standard/ERC4626Handler.t.sol index cd1cde0..e989d99 100644 --- a/test/enigma-dark-invariants/handlers/standard/ERC4626Handler.t.sol +++ b/test/enigma-dark-invariants/handlers/standard/ERC4626Handler.t.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.19; // Interfaces import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol"; import {IERC4626} from "openzeppelin-contracts/interfaces/IERC4626.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; // Libraries import "forge-std/console.sol"; @@ -105,6 +106,16 @@ abstract contract ERC4626Handler is BaseHandler { } } + function skim(uint8 i, uint8 j) external { + // Get one of the three actors randomly + address receiver = _getRandomActor(i); + + // Get one of the vaults randomly + address target = _getRandomVault(j); + + IEVault(target).skim(type(uint256).max, receiver); + } + /////////////////////////////////////////////////////////////////////////////////////////////// // HELPERS // /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol index 6c3d963..ee8cc79 100644 --- a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol @@ -26,7 +26,11 @@ abstract contract MaglevHandler is BaseHandler { // ACTIONS // /////////////////////////////////////////////////////////////////////////////////////////////// - function swap(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In, uint8 i) public setup maglevDeployed { + function swap(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In, uint8 i) + public + setup + maglevDeployed + { bool success; bytes memory returnData; @@ -63,10 +67,6 @@ abstract contract MaglevHandler is BaseHandler { } else { _constantSumPostconditions(); } - - //assert((amount0Out > 1 && amount1In > 1) || (amount1Out > 1 && amount0In > 1)); - - _checkCoverage(amount0Out, 0, type(uint256).max); } else { revert("MaglevHandler: swap failed"); } @@ -74,7 +74,7 @@ abstract contract MaglevHandler is BaseHandler { delete receiver; } - function roundtripSwap(uint256 amount, uint8 i) external setup { + function roundtripSwap(uint256 amount, uint8 i) external setup maglevDeployed { uint256 amount0Out; uint256 amount1Out; uint256 amount0In; @@ -120,10 +120,10 @@ abstract contract MaglevHandler is BaseHandler { uint256 actorInBalanceAfter = assetTSTIn.balanceOf(roundtripSwapActor); // HSPOST - //assertLe(actorInBalanceAfter, actorInBalanceBefore, HSPOST_SWAP_B); + assertLe(actorInBalanceAfter, actorInBalanceBefore, HSPOST_SWAP_B); } - function quoteExactInput(uint256 amountIn, bool dir) external { + function quoteExactInput(uint256 amountIn, bool dir) external maglevDeployed {// TODO add if quote says to do x it should work and that quote shouldn't overestimate (address assetIn, address assetOut) = _getAssetsByDir(dir); try maglev.quoteExactInput(assetIn, assetOut, amountIn) returns (uint256 amountOut) {} @@ -133,7 +133,7 @@ abstract contract MaglevHandler is BaseHandler { } } - function quoteExactOutput(uint256 amountIn, bool dir) external { + function quoteExactOutput(uint256 amountIn, bool dir) external maglevDeployed { (address assetIn, address assetOut) = _getAssetsByDir(dir); try maglev.quoteExactOutput(assetIn, assetOut, amountIn) returns (uint256 amountOut) {} @@ -169,7 +169,7 @@ abstract contract MaglevHandler is BaseHandler { ); } - //assertGe(defaultVarsAfter.holderNAV, defaultVarsBefore.holderNAV, HSPOST_SWAP_A);// TODO remove + 1 when rounding is fixed + //assertGe(defaultVarsAfter.holderNAV, defaultVarsBefore.holderNAV, HSPOST_SWAP_A); /// @dev HSPOST_RESERVES_A diff --git a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol index 456610f..aafddba 100644 --- a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol +++ b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol @@ -43,4 +43,11 @@ abstract contract PostconditionsSpec { string constant HSPOST_RESERVES_C = "HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed"; + + + // TODO + // - if it has debt it shouldnt have balance + /* + - donations should only increase nav or reduce leverage + */ } From 4a59f1419c47a9127c3b62a08e84350c29621e7b Mon Sep 17 00:00:00 2001 From: Elpacos Date: Wed, 12 Mar 2025 16:25:23 +0100 Subject: [PATCH 13/18] chore: migrate maglev suite to eulerswap setup --- .../CryticToFoundry.t.sol | 7 +- .../HandlerAggregator.t.sol | 12 ++- test/enigma-dark-invariants/README.md | 2 +- test/enigma-dark-invariants/Setup.t.sol | 67 ++++++++----- test/enigma-dark-invariants/Tester.t.sol | 2 +- .../base/BaseHandler.t.sol | 8 +- .../base/BaseStorage.t.sol | 26 ++--- .../base/BaseTest.t.sol | 48 +++++---- .../setup/EulerSwapSetupHandler.t.sol | 84 ++++++++++++++++ .../handlers/setup/MaglevSetupHandler.t.sol | 87 ----------------- .../simulators/DonationAttackHandler.t.sol | 4 +- ...evHandler.t.sol => EulerSwapHandler.t.sol} | 80 ++++----------- .../swap/EulerSwapPeripheryHandler.t.sol | 97 +++++++++++++++++++ .../hooks/DefaultBeforeAfterHooks.t.sol | 6 +- 14 files changed, 301 insertions(+), 229 deletions(-) create mode 100644 test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol delete mode 100644 test/enigma-dark-invariants/handlers/setup/MaglevSetupHandler.t.sol rename test/enigma-dark-invariants/handlers/swap/{MaglevHandler.t.sol => EulerSwapHandler.t.sol} (67%) create mode 100644 test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol diff --git a/test/enigma-dark-invariants/CryticToFoundry.t.sol b/test/enigma-dark-invariants/CryticToFoundry.t.sol index 1e530ff..96c0476 100644 --- a/test/enigma-dark-invariants/CryticToFoundry.t.sol +++ b/test/enigma-dark-invariants/CryticToFoundry.t.sol @@ -6,7 +6,6 @@ import "forge-std/Test.sol"; import "forge-std/console.sol"; // Contracts -import {MaglevEulerSwap} from "src/MaglevEulerSwap.sol"; import {Invariants} from "./Invariants.t.sol"; import {Setup} from "./Setup.t.sol"; @@ -23,7 +22,7 @@ contract CryticToFoundry is Invariants, Setup { function setUp() public { // Deploy protocol contracts - _setUp(Curve.EULER_SWAP); + _setUp(); // Initialize handler contracts _setUpHandlers(); @@ -41,7 +40,7 @@ contract CryticToFoundry is Invariants, Setup { // POSTCONDITIONS REPLAY // /////////////////////////////////////////////////////////////////////////////////////////////// - function test_replay_swap() public { +/* function test_replay_swap() public { //@audit-issue is possible to extract value from the protocol 1 wei of value Tester.setupMaglev(10, 50e18, 50e18, 0, Curve(0), MaglevEulerSwap.EulerSwapParams(1e18, 1e18, 0.4e18, 0.85e18)); Tester.mint(2000000, 0, 0); @@ -67,7 +66,7 @@ contract CryticToFoundry is Invariants, Setup { Tester.setupMaglev(10, 50e18, 50e18, 0, Curve(0), MaglevEulerSwap.EulerSwapParams(1e18, 1e18, 0.4e18, 0.85e18)); Tester.swap(1516752036338334875613876384, 1645511910635276617001867226888, 2, 0, 0); Tester.roundtripSwap(200000000, 0); - } + } */ /////////////////////////////////////////////////////////////////////////////////////////////// // INVARIANTS REPLAY // diff --git a/test/enigma-dark-invariants/HandlerAggregator.t.sol b/test/enigma-dark-invariants/HandlerAggregator.t.sol index 001f0de..ca7a945 100644 --- a/test/enigma-dark-invariants/HandlerAggregator.t.sol +++ b/test/enigma-dark-invariants/HandlerAggregator.t.sol @@ -5,8 +5,9 @@ pragma solidity ^0.8.19; import {EVCHandler} from "./handlers/euler/EVCHandler.t.sol"; import {ERC20Handler} from "./handlers/standard/ERC20Handler.t.sol"; import {ERC4626Handler} from "./handlers/standard/ERC4626Handler.t.sol"; -import {MaglevHandler} from "./handlers/swap/MaglevHandler.t.sol"; -import {MaglevSetupHandler} from "./handlers/setup/MaglevSetupHandler.t.sol"; +import {EulerSwapHandler} from "./handlers/swap/EulerSwapHandler.t.sol"; +import {EulerSwapPeripheryHandler} from "./handlers/swap/EulerSwapPeripheryHandler.t.sol"; +import {EulerSwapSetupHandler} from "./handlers/setup/EulerSwapSetupHandler.t.sol"; // Simulator Handler contracts, import {DonationAttackHandler} from "./handlers/simulators/DonationAttackHandler.t.sol"; @@ -15,10 +16,11 @@ import {PriceOracleHandler} from "./handlers/simulators/PriceOracleHandler.t.sol /// @notice Helper contract to aggregate all handler contracts, inherited in BaseInvariants abstract contract HandlerAggregator is EVCHandler, // Euler handlers - ERC20Handler, // Module handlers + ERC20Handler, // Standard Handlers ERC4626Handler, - MaglevHandler, - MaglevSetupHandler, + EulerSwapHandler, // Swap Handlers + EulerSwapPeripheryHandler, + EulerSwapSetupHandler, // Setup Handlers DonationAttackHandler, // Simulator handlers PriceOracleHandler { diff --git a/test/enigma-dark-invariants/README.md b/test/enigma-dark-invariants/README.md index ff98c53..359f0ef 100644 --- a/test/enigma-dark-invariants/README.md +++ b/test/enigma-dark-invariants/README.md @@ -8,7 +8,7 @@ Developed by [vnmrtz.eth](https://x.com/vn_martinez_) from [Enigma Dark](https:/
-The Actor Based Invariant Testing Suite is a framework for performing comprehensive invariant testing of the Euler Maglev protocol. Using an actor-based model, it simulates realistic scenarios with various entities interacting with the system, ensuring that protocol invariants and postconditions hold under an extensive range of conditions. +The Actor Based Invariant Testing Suite is a framework for performing comprehensive invariant testing of the EulerSwap protocol. Using an actor-based model, it simulates realistic scenarios with various entities interacting with the system, ensuring that protocol invariants and postconditions hold under an extensive range of conditions. The suite is designed to support multi-actor tooling, randomizing actions, parameters, actor roles, and asset selection to explore edge cases and ensure the robustness of a protocol. diff --git a/test/enigma-dark-invariants/Setup.t.sol b/test/enigma-dark-invariants/Setup.t.sol index 9959f35..bbd0c1c 100644 --- a/test/enigma-dark-invariants/Setup.t.sol +++ b/test/enigma-dark-invariants/Setup.t.sol @@ -15,6 +15,9 @@ import {SequenceRegistry} from "evk/SequenceRegistry/SequenceRegistry.sol"; import {Base} from "evk/EVault/shared/Base.sol"; import {Dispatch} from "evk/EVault/Dispatch.sol"; import {EVault} from "evk/EVault/EVault.sol"; +import {EulerSwap} from "src/EulerSwap.sol"; +import {EulerSwapPeriphery} from "src/EulerSwapPeriphery.sol"; +import {EulerSwapFactory} from "src/EulerSwapFactory.sol"; // Modules import {Initialize} from "evk/EVault/modules/Initialize.sol"; @@ -39,25 +42,35 @@ import {Actor} from "./utils/Actor.sol"; /// @notice Setup contract for the invariant test Suite, inherited by Tester contract Setup is BaseTest { - function _setUp(Curve _curveType) internal { - // Deploy protocol contracts and protocol actors - _deployEulerEnvContracts(); + function _setUp() internal { + // Deploy protocol contracts + _deployEulerEVCContracts(); + + // Deploy suite assets + _deployAssets(); // Deploy vaults - _deployVaults(); + _deployEVaults(); // Deploy actors _setUpActors(); - // Deploy and setup maglev - _setUpMaglev(_curveType); + // Setup eulerswap holder and periphery + _setUpEulerSwap(); } - /// @notice Deploy euler env contracts - function _deployEulerEnvContracts() internal { + /////////////////////////////////////////////////////////////////////////////////////////////// + // EVC // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @notice Deploy euler EVC & Environment contracts + function _deployEulerEVCContracts() internal { // Deploy the EVC evc = new EthereumVaultConnector(); + // Deploy the factory + factory = new GenericFactory(address(this)); + // Deploy permit2 contract permit2 = DeployPermit2.deployPermit2(); @@ -75,7 +88,7 @@ contract Setup is BaseTest { // VAULTS // /////////////////////////////////////////////////////////////////////////////////////////////// - function _deployVaults() internal { + function _deployEVaults() internal { // Deploy the modules Base.Integrations memory integrations = Base.Integrations(address(evc), address(protocolConfig), sequenceRegistry, balanceTracker, permit2); @@ -95,18 +108,8 @@ contract Setup is BaseTest { address evaultImpl = address(new EVault(integrations, modules)); // Deploy the vault factory and set the implementation - factory = new GenericFactory(address(this)); factory.setImplementation(evaultImpl); - // Deploy base assets - assetTST = new TestERC20("Test Token", "TST", 18); - baseAssets.push(address(assetTST)); - oracle.setPrice(address(assetTST), unitOfAccount, 1e18); - - assetTST2 = new TestERC20("Test Token 2", "TST2", 18); // TODO change decimals - baseAssets.push(address(assetTST2)); - oracle.setPrice(address(assetTST2), unitOfAccount, 1e18); - // Deploy the vaults eTST = _deployEVault(address(assetTST)); vaults.push(address(eTST)); @@ -126,12 +129,29 @@ contract Setup is BaseTest { eVault.setFeeReceiver(feeRecipient); } + function _deployAssets() internal { + // Deploy base assets + assetTST = new TestERC20("Test Token", "TST", 18); + baseAssets.push(address(assetTST)); + oracle.setPrice(address(assetTST), unitOfAccount, 1e18); + + assetTST2 = new TestERC20("Test Token 2", "TST2", 18); // TODO change decimals + baseAssets.push(address(assetTST2)); + oracle.setPrice(address(assetTST2), unitOfAccount, 1e18); + } + /////////////////////////////////////////////////////////////////////////////////////////////// - // MAGLEV // + // EULER SWAP // /////////////////////////////////////////////////////////////////////////////////////////////// - function _setUpMaglev(Curve _curveType) internal { - // Setup maglev lp as the first actor + function _setUpEulerSwap() internal { + // Deploy the periphery + periphery = new EulerSwapPeriphery(); + + // Deploy the euler swap factory + eulerSwapfactory = new EulerSwapFactory(address(evc)); + + // Setup eulerswap lp as the first actor holder = address(actors[USER1]); } @@ -152,9 +172,10 @@ contract Setup is BaseTest { tokens[0] = address(assetTST); tokens[1] = address(assetTST2); - address[] memory contracts_ = new address[](2); + address[] memory contracts_ = new address[](3); contracts_[0] = address(eTST); contracts_[1] = address(eTST2); + contracts_[2] = address(periphery); for (uint256 i; i < NUMBER_OF_ACTORS; i++) { // Deploy actor proxies and approve system contracts_ diff --git a/test/enigma-dark-invariants/Tester.t.sol b/test/enigma-dark-invariants/Tester.t.sol index 92fa058..7697912 100644 --- a/test/enigma-dark-invariants/Tester.t.sol +++ b/test/enigma-dark-invariants/Tester.t.sol @@ -18,7 +18,7 @@ contract Tester is Invariants, Setup { /// @dev Foundry compatibility faster setup debugging function setUp() internal { // Deploy protocol contracts and protocol actors - _setUp(Curve.EULER_SWAP); + _setUp(); // Initialize handler contracts _setUpHandlers(); diff --git a/test/enigma-dark-invariants/base/BaseHandler.t.sol b/test/enigma-dark-invariants/base/BaseHandler.t.sol index 62a986b..9af4cd0 100644 --- a/test/enigma-dark-invariants/base/BaseHandler.t.sol +++ b/test/enigma-dark-invariants/base/BaseHandler.t.sol @@ -22,13 +22,13 @@ contract BaseHandler is HookAggregator { // MODIFIERS // /////////////////////////////////////////////////////////////////////////////////////////////// - modifier maglevNotDeployed() { - if (address(maglev) != address(0)) revert("BaseHandler: Maglev already deployed on this trace"); + modifier eulerSwapNotDeployed() { + if (address(eulerSwap) != address(0)) revert("BaseHandler: EulerSwap already deployed on this trace"); _; } - modifier maglevDeployed() { - if (address(maglev) == address(0)) revert("BaseHandler: Maglev has not been deployed on this trace"); + modifier eulerSwapDeployed() { + if (address(eulerSwap) == address(0)) revert("BaseHandler: EulerSwap has not been deployed on this trace"); _; } diff --git a/test/enigma-dark-invariants/base/BaseStorage.t.sol b/test/enigma-dark-invariants/base/BaseStorage.t.sol index 663d9fb..a3e2498 100644 --- a/test/enigma-dark-invariants/base/BaseStorage.t.sol +++ b/test/enigma-dark-invariants/base/BaseStorage.t.sol @@ -7,10 +7,12 @@ pragma solidity ^0.8.19; import {EthereumVaultConnector} from "ethereum-vault-connector/EthereumVaultConnector.sol"; import {GenericFactory} from "evk/GenericFactory/GenericFactory.sol"; import {ProtocolConfig} from "evk/ProtocolConfig/ProtocolConfig.sol"; +import {EulerSwap} from "src/EulerSwap.sol"; +import {EulerSwapPeriphery} from "src/EulerSwapPeriphery.sol"; +import {EulerSwapFactory} from "src/EulerSwapFactory.sol"; // Interfaces import {IEVault} from "evk/EVault/IEVault.sol"; -import {IMaglevBase} from "src/interfaces/IMaglevBase.sol"; // Mock Contracts import {TestERC20} from "test/enigma-dark-invariants/utils/mocks/TestERC20.sol"; @@ -73,14 +75,10 @@ abstract contract BaseStorage { TestERC20 assetTST; TestERC20 assetTST2; - /// @notice Maglev contract - /* ___________________________________________ - ________ ______________________>__ - []_[]||[| |]||[]_[]_[]|||[]_[]_[]||[| - ===~-~==/_\==~-~======~-~======~-~==/______ - ::::::::::::::::::::::::::::::::::::::::::: - */ - IMaglevBase maglev; + /// @notice EulerSwap contracts + EulerSwap eulerSwap; + EulerSwapPeriphery periphery; + EulerSwapFactory eulerSwapfactory; /// @notice Extra contracts MockPriceOracle oracle; @@ -88,10 +86,6 @@ abstract contract BaseStorage { address balanceTracker; address sequenceRegistry; - /// @notice curve selector - - Curve curve; - /////////////////////////////////////////////////////////////////////////////////////////////// // EXTRA VARIABLES // /////////////////////////////////////////////////////////////////////////////////////////////// @@ -111,10 +105,4 @@ abstract contract BaseStorage { /////////////////////////////////////////////////////////////////////////////////////////////// // STRUCTS // /////////////////////////////////////////////////////////////////////////////////////////////// - - enum Curve { - EULER_SWAP, - PRODUCT, - SUM - } } diff --git a/test/enigma-dark-invariants/base/BaseTest.t.sol b/test/enigma-dark-invariants/base/BaseTest.t.sol index fe51b9b..986edf5 100644 --- a/test/enigma-dark-invariants/base/BaseTest.t.sol +++ b/test/enigma-dark-invariants/base/BaseTest.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.19; // Interfaces import {IERC20} from "openzeppelin-contracts/interfaces/IERC20.sol"; -import {IMaglevBase} from "src/interfaces/IMaglevBase.sol"; +import {IEulerSwap} from "src/interfaces/IEulerSwap.sol"; // Libraries import {Vm} from "forge-std/Base.sol"; @@ -16,10 +16,7 @@ import {StdAsserts} from "../utils/StdAsserts.sol"; import {CoverageChecker} from "../utils/CoverageChecker.sol"; // Contracts -import {MaglevBase} from "src/MaglevBase.sol"; -import {MaglevConstantSum} from "src/MaglevConstantSum.sol"; -import {MaglevConstantProduct} from "src/MaglevConstantProduct.sol"; -import {MaglevEulerSwap} from "src/MaglevEulerSwap.sol"; +import {EulerSwap} from "src/EulerSwap.sol"; // Base import {BaseStorage} from "./BaseStorage.t.sol"; @@ -128,7 +125,7 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU } /////////////////////////////////////////////////////////////////////////////////////////////// - // MAGLEV SPECIFIC HELPERS // + // EULER-SWAP SPECIFIC HELPERS // /////////////////////////////////////////////////////////////////////////////////////////////// function _getHolderNAV() internal view returns (int256) { @@ -145,22 +142,33 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU return int256(balValue) - int256(debtValue); } - function _deployMaglevEulerSwap( - MaglevBase.BaseParams memory _baseParams, - MaglevEulerSwap.EulerSwapParams memory _eulerSwapParams - ) internal { - maglev = IMaglevBase(address(new MaglevEulerSwap(_baseParams, _eulerSwapParams))); - } + function _createEulerSwap( // TODO should we deploy from the factory instead? + uint112 debtLimitA, uint112 debtLimitB, uint256 fee, uint256 px, uint256 py, uint256 cx, uint256 cy) + internal + { + eulerSwap = new EulerSwap( + _getEulerSwapParams(debtLimitA, debtLimitB, fee), + IEulerSwap.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) + ); - function _deployMaglevConstantProduct(MaglevBase.BaseParams memory _baseParams) internal { - maglev = IMaglevBase(address(new MaglevConstantProduct(_baseParams))); + vm.prank(holder); + evc.setAccountOperator(holder, address(eulerSwap), true); } - function _deployMaglevConstantSum(MaglevBase.BaseParams memory _baseParams) internal { - maglev = IMaglevBase( - address( - new MaglevConstantSum(_baseParams, MaglevConstantSum.ConstantSumParams({priceX: 1e18, priceY: 1e18})) - ) - ); + function _getEulerSwapParams(uint112 reserve0, uint112 reserve1, uint256 fee) + internal + view + returns (EulerSwap.Params memory) + { + return IEulerSwap.Params({ + vault0: address(eTST), + vault1: address(eTST2), + eulerAccount: holder, + equilibriumReserve0: reserve0, + equilibriumReserve1: reserve1, + currReserve0: reserve0, + currReserve1: reserve1, + fee: fee + }); } } diff --git a/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol b/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol new file mode 100644 index 0000000..314e32c --- /dev/null +++ b/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Interfaces +import {IEulerSwap} from "src/interfaces/IEulerSwap.sol"; + +// Contracts +import {EulerSwap} from "src/EulerSwap.sol"; + +// Libraries +import "forge-std/console.sol"; + +// Test Contracts +import {BaseHandler} from "../../base/BaseHandler.t.sol"; + +/// @title EulerSwapSetupHandler +/// @notice Handler test contract for a set of actions +abstract contract EulerSwapSetupHandler is BaseHandler { + /////////////////////////////////////////////////////////////////////////////////////////////// + // STATE VARIABLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // ACTIONS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function setupEulerSwap( + uint8 leverage, + uint112 initialAmount0, + uint112 initialAmount1, + uint256 fee, + IEulerSwap.CurveParams memory curveParams + ) public eulerSwapNotDeployed { + /// --- CLAMPING PARAMETERS --- + + // Restrict leverage to a maximum of x10 + leverage = uint8(clampBetween(leverage, 1, 10)); + + // Ensure initial deposit amounts are at least 1000 tokens and within leverage limits + initialAmount0 = uint112(clampBetween(initialAmount0, 1000e18, type(uint112).max / leverage)); + initialAmount1 = uint112(clampBetween(initialAmount1, 1000e18, type(uint112).max / leverage)); + + // Calculate maximum debt limits based on leverage + uint112 debtLimit0 = initialAmount0 * leverage; + uint112 debtLimit1 = initialAmount1 * leverage; + + // Clamp price values within a reasonable range (0.1 to 10) + curveParams.priceX = clampBetween(curveParams.priceX, 0.1e18, 10e18); // TODO should this setup oracles as well? + curveParams.priceY = clampBetween(curveParams.priceY, 0.1e18, 10e18); + + // Clamp concentration between 0.1e18 and 1e18 + curveParams.concentrationX = clampBetween(curveParams.concentrationX, 0.1e18, 1e18); + curveParams.concentrationY = clampBetween(curveParams.concentrationY, 0.1e18, 1e18); + + /// --- INITIAL DEPOSITS --- + + // Deposit initial funds into vaults on behalf of the holder + vm.prank(holder); + eTST.deposit(initialAmount0, holder); + + vm.prank(holder); + eTST2.deposit(initialAmount1, holder); + + /// --- DEPLOY EULER SWAP CONTRACT --- + + _createEulerSwap( + debtLimit0, + debtLimit1, + fee, + curveParams.priceX, + curveParams.priceY, + curveParams.concentrationX, + curveParams.concentrationY + ); + + /// --- SETUP ACTORS' TOKEN APPROVALS --- + + // Configure actors' token approvals for the eulerSwap contract + address[] memory contracts = new address[](1); + contracts[0] = address(eulerSwap); + + _setupActorApprovals(baseAssets, contracts); + } +} diff --git a/test/enigma-dark-invariants/handlers/setup/MaglevSetupHandler.t.sol b/test/enigma-dark-invariants/handlers/setup/MaglevSetupHandler.t.sol deleted file mode 100644 index bda5b81..0000000 --- a/test/enigma-dark-invariants/handlers/setup/MaglevSetupHandler.t.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -// Contracts -import {MaglevBase} from "src/MaglevBase.sol"; -import {MaglevEulerSwap} from "src/MaglevEulerSwap.sol"; - -// Libraries -import "forge-std/console.sol"; - -// Test Contracts -import {Actor} from "../../utils/Actor.sol"; -import {BaseHandler} from "../../base/BaseHandler.t.sol"; - -/// @title MaglevSetupHandler -/// @notice Handler test contract for a set of actions -abstract contract MaglevSetupHandler is BaseHandler { - /////////////////////////////////////////////////////////////////////////////////////////////// - // STATE VARIABLES // - /////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////// - // ACTIONS // - /////////////////////////////////////////////////////////////////////////////////////////////// - - function setupMaglev( - uint8 leverage, - uint112 initialAmount0, - uint112 initialAmount1, - uint256 fee, - Curve, /*_curveType*/ - MaglevEulerSwap.EulerSwapParams memory eulerSwapParams - ) public maglevNotDeployed { - // Clamp leverage at x10 - leverage = uint8(clampBetween(leverage, 1, 10)); - - // Clamp minimum amount at 1000 tokens - initialAmount0 = uint112(clampBetween(initialAmount0, 1000e18, type(uint112).max)); - initialAmount1 = uint112(clampBetween(initialAmount1, 1000e18, type(uint112).max)); - - uint112 debtLimit0 = initialAmount0 * leverage; - uint112 debtLimit1 = initialAmount1 * leverage; - - // Clamp concentration between 0.1e18 and 1e18 - eulerSwapParams.priceX = clampBetween(eulerSwapParams.priceX, 0.1e18, 1e18); - eulerSwapParams.priceY = clampBetween(eulerSwapParams.priceY, 0.1e18, 1e18); - - // Deposit initial funds on the vaults as the holder - vm.prank(holder); - eTST.deposit(initialAmount0, holder); - vm.prank(holder); - eTST2.deposit(initialAmount1, holder); - - // Setup the maglev params - MaglevBase.BaseParams memory baseParams = MaglevBase.BaseParams({ - evc: address(evc), - vault0: address(eTST), - vault1: address(eTST2), - myAccount: holder, - debtLimit0: debtLimit0, - debtLimit1: debtLimit1, - fee: fee - }); - - Curve _curveType = Curve.EULER_SWAP; // TODO remove hardcoded curve type -> try other curves on different instances - - /// Deploy the specific curve type maglev contract - if (_curveType == Curve.EULER_SWAP) { - _deployMaglevEulerSwap(baseParams, eulerSwapParams); - } else if (_curveType == Curve.PRODUCT) { - _deployMaglevConstantProduct(baseParams); - } else { - _deployMaglevConstantSum(baseParams); - } - - // Set maglev as operator for the lp and call configure - vm.prank(holder); - evc.setAccountOperator(holder, address(maglev), true); - maglev.configure(); - - // Setup actors token approvals to maglev - address[] memory contracts = new address[](1); - contracts[0] = address(maglev); - - _setupActorApprovals(baseAssets, contracts); - } -} diff --git a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol index f104845..e68f141 100644 --- a/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/simulators/DonationAttackHandler.t.sol @@ -26,10 +26,10 @@ contract DonationAttackHandler is BaseHandler { /// @notice This function transfers any amount of assets to a contract in the system simulating /// a big range of donation attacks - function donateUnderlying(uint256 amount, uint8 i) external maglevDeployed { + function donateUnderlying(uint256 amount, uint8 i) external eulerSwapDeployed { TestERC20 _token = TestERC20(_getRandomBaseAsset(i)); - address target = address(maglev); + address target = address(eulerSwap); _token.mint(address(this), amount); diff --git a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/EulerSwapHandler.t.sol similarity index 67% rename from test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol rename to test/enigma-dark-invariants/handlers/swap/EulerSwapHandler.t.sol index ee8cc79..1f73509 100644 --- a/test/enigma-dark-invariants/handlers/swap/MaglevHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/EulerSwapHandler.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.19; // Interfaces import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {IMaglevBase} from "src/interfaces/IMaglevBase.sol"; +import {IEulerSwap} from "src/interfaces/IEulerSwap.sol"; // Libraries import "forge-std/console.sol"; @@ -12,9 +12,9 @@ import "forge-std/console.sol"; import {Actor} from "../../utils/Actor.sol"; import {BaseHandler} from "../../base/BaseHandler.t.sol"; -/// @title MaglevHandler +/// @title EulerSwapHandler /// @notice Handler test contract for a set of actions -abstract contract MaglevHandler is BaseHandler { +abstract contract EulerSwapHandler is BaseHandler { /////////////////////////////////////////////////////////////////////////////////////////////// // STATE VARIABLES // /////////////////////////////////////////////////////////////////////////////////////////////// @@ -26,10 +26,12 @@ abstract contract MaglevHandler is BaseHandler { // ACTIONS // /////////////////////////////////////////////////////////////////////////////////////////////// + // TODO activate() function + function swap(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In, uint8 i) public setup - maglevDeployed + eulerSwapDeployed { bool success; bytes memory returnData; @@ -37,44 +39,37 @@ abstract contract MaglevHandler is BaseHandler { // Get one of the three actors randomly receiver = roundtripSwapActor == address(0) ? _getRandomActor(i) : roundtripSwapActor; - address target = address(maglev); + address target = address(eulerSwap); //if (amount0Out >= 2 ether && amount1In >= 10 ether) assert(false); - //require(amount0Out > 1 ether || amount1Out > 1 ether, "MaglevHandler: Invalid amount out"); + //require(amount0Out > 1 ether || amount1Out > 1 ether, "EulerSwapHandler: Invalid amount out"); if (amount0In > 0) { - _transferByActor(address(assetTST), address(maglev), amount0In); + _transferByActor(address(assetTST), address(eulerSwap), amount0In); } if (amount1In > 0) { - _transferByActor(address(assetTST2), address(maglev), amount1In); + _transferByActor(address(assetTST2), address(eulerSwap), amount1In); } _before(); (success, returnData) = - actor.proxy(target, abi.encodeWithSelector(IMaglevBase.swap.selector, amount0Out, amount1Out, receiver, "")); + actor.proxy(target, abi.encodeWithSelector(IEulerSwap.swap.selector, amount0Out, amount1Out, receiver, "")); if (success) { _after(); - _commonPostconditions(amount0Out, amount1Out, amount0In, amount1In); - - if (curve == Curve.EULER_SWAP) { - _eulerSwapPostconditions(); - } else if (curve == Curve.PRODUCT) { - _constantProductPostconditions(); - } else { - _constantSumPostconditions(); - } + // POSTCONDITIONS + _eulerSwapPostconditions(amount0Out, amount1Out, amount0In, amount1In); } else { - revert("MaglevHandler: swap failed"); + revert("EulerSwapHandler: swap failed"); } delete receiver; } - function roundtripSwap(uint256 amount, uint8 i) external setup maglevDeployed { + function roundtripSwap(uint256 amount, uint8 i) external setup eulerSwapDeployed { uint256 amount0Out; uint256 amount1Out; uint256 amount0In; @@ -90,11 +85,11 @@ abstract contract MaglevHandler is BaseHandler { if (i % 2 == 0) { // token0 -> token1 case amount0In = amount; - amount1Out = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount0In); + amount1Out = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amount0In); } else { // token1 -> token0 case amount1In = amount; - amount0Out = maglev.quoteExactInput(address(assetTST2), address(assetTST), amount1In); + amount0Out = periphery.quoteExactInput(address(eulerSwap), address(assetTST2), address(assetTST), amount1In); } swap(amount0Out, amount1Out, amount0In, amount1In, 0); @@ -104,13 +99,13 @@ abstract contract MaglevHandler is BaseHandler { if (i % 2 == 0) { // token0 -> token1 case amount1In = amount1Out; - amount0Out = maglev.quoteExactInput(address(assetTST2), address(assetTST), amount1In); + amount0Out = periphery.quoteExactInput(address(eulerSwap), address(assetTST2), address(assetTST), amount1In); delete amount1Out; // @audit seems like input amounts are kinda delayed check uniswap v2 delete amount0In; } else { // token1 -> token0 case amount0In = amount0Out; - amount1Out = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount0In); + amount1Out = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amount0In); delete amount0Out; delete amount1In; } @@ -123,32 +118,12 @@ abstract contract MaglevHandler is BaseHandler { assertLe(actorInBalanceAfter, actorInBalanceBefore, HSPOST_SWAP_B); } - function quoteExactInput(uint256 amountIn, bool dir) external maglevDeployed {// TODO add if quote says to do x it should work and that quote shouldn't overestimate - (address assetIn, address assetOut) = _getAssetsByDir(dir); - - try maglev.quoteExactInput(assetIn, assetOut, amountIn) returns (uint256 amountOut) {} - catch Error(string memory) { - // HSPOST - assertTrue(false, NR_QUOTE_A); - } - } - - function quoteExactOutput(uint256 amountIn, bool dir) external maglevDeployed { - (address assetIn, address assetOut) = _getAssetsByDir(dir); - - try maglev.quoteExactOutput(assetIn, assetOut, amountIn) returns (uint256 amountOut) {} - catch Error(string memory) { - // HSPOST - assertTrue(false, NR_QUOTE_B); - } - } - /////////////////////////////////////////////////////////////////////////////////////////////// // HSPOST: SWAP // /////////////////////////////////////////////////////////////////////////////////////////////// /// @notice Postconditions common to all three curves - function _commonPostconditions(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In) + function _eulerSwapPostconditions(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In) internal { /// @dev HSPOST_SWAP_C @@ -209,19 +184,4 @@ abstract contract MaglevHandler is BaseHandler { ); } } - - /// @notice Postconditions for EulerSwap curve - function _eulerSwapPostconditions() internal { - // TODO Implement postconditions - } - - /// @notice Postconditions for ConstantProduct curve - function _constantProductPostconditions() internal { - // TODO Implement postconditions - } - - /// @notice ºPostconditions for ConstantSum curve - function _constantSumPostconditions() internal { - // TODO Implement postconditions - } } diff --git a/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol new file mode 100644 index 0000000..73d18b2 --- /dev/null +++ b/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +// Interfaces +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IEulerSwapPeriphery} from "src/interfaces/IEulerSwapPeriphery.sol"; + +// Libraries +import "forge-std/console.sol"; + +// Test Contracts +import {Actor} from "../../utils/Actor.sol"; +import {BaseHandler} from "../../base/BaseHandler.t.sol"; + +/// @title EulerSwapPeripheryHandler +/// @notice Handler test contract for a set of actions +abstract contract EulerSwapPeripheryHandler is BaseHandler { + /////////////////////////////////////////////////////////////////////////////////////////////// + // STATE VARIABLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// + // ACTIONS // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function swapExactIn(uint256 amountIn, uint256 amountOutMin, bool dir) public setup eulerSwapDeployed { + bool success; + bytes memory returnData; + + address target = address(periphery); + + (address tokenIn, address tokenOut) = _getAssetsByDir(dir); + + _before(); + (success, returnData) = actor.proxy( + target, + abi.encodeWithSelector( + IEulerSwapPeriphery.swapExactIn.selector, address(eulerSwap), tokenIn, tokenOut, amountIn, amountOutMin + ) + ); + + if (success) { + _after(); + + // _eulerSwapPostconditions(amount0Out, amount1Out, amount0In, amount1In); // TODO check postconditions + } else { + revert("EulerSwapPeripheryHandler: swapExactIn failed"); + } + } + + function swapExactOut(uint256 amountOut, uint256 amountInMax, bool dir) public setup eulerSwapDeployed { + bool success; + bytes memory returnData; + + address target = address(periphery); + + (address tokenIn, address tokenOut) = _getAssetsByDir(dir); + + _before(); + (success, returnData) = actor.proxy( + target, + abi.encodeWithSelector( + IEulerSwapPeriphery.swapExactOut.selector, address(eulerSwap), tokenIn, tokenOut, amountOut, amountInMax + ) + ); + + if (success) { + _after(); + + // _eulerSwapPostconditions(amount0Out, amount1Out, amount0In, amount1In); // TODO check postconditions + } else { + revert("EulerSwapPeripheryHandler: swapExactOut failed"); + } + } + + function quoteExactInput(uint256 amountIn, bool dir) external eulerSwapDeployed { + (address tokenIn, address tokenOut) = _getAssetsByDir(dir); + + try periphery.quoteExactInput(address(eulerSwap), tokenIn, tokenOut, amountIn) returns (uint256 tokenIn_) {} + catch Error(string memory) { + // HSPOST + assertTrue(false, NR_QUOTE_A); + } + } + + function quoteExactOutput(uint256 amountOut, bool dir) external eulerSwapDeployed { + (address tokenIn, address tokenOut) = _getAssetsByDir(dir); + + try periphery.quoteExactOutput(address(eulerSwap), tokenIn, tokenOut, amountOut) returns (uint256 tokenOut_) {} + catch Error(string memory) { + // HSPOST + assertTrue(false, NR_QUOTE_B); + } + } + + // getLimits //TODO +} diff --git a/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol b/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol index 5042d0e..6e67125 100644 --- a/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol +++ b/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol @@ -77,10 +77,10 @@ abstract contract DefaultBeforeAfterHooks is BaseHooks { // Holder _defaultVars.holderNAV = _getHolderNAV(); _defaultVars.holderETSTAssets = - eTST.convertToAssets(eTST.balanceOf(holder)) + assetTST.balanceOf(address(maglev)); - /// @dev adding maglev balance to take donations into account + eTST.convertToAssets(eTST.balanceOf(holder)) + assetTST.balanceOf(address(eulerSwap)); + /// @dev adding eulerSwap balance to take donations into account _defaultVars.holderETST2Assets = - eTST2.convertToAssets(eTST2.balanceOf(holder)) + assetTST2.balanceOf(address(maglev)); + eTST2.convertToAssets(eTST2.balanceOf(holder)) + assetTST2.balanceOf(address(eulerSwap)); _defaultVars.holderETSTDebt = eTST.debtOf(holder); _defaultVars.holderETST2Debt = eTST2.debtOf(holder); } From 5af6233317754156c83e1ffc5ae34fc0b560613a Mon Sep 17 00:00:00 2001 From: Elpacos Date: Mon, 24 Mar 2025 15:17:31 +0100 Subject: [PATCH 14/18] chore: add new global invariants --- .../CryticToFoundry.t.sol | 5 +- test/enigma-dark-invariants/Invariants.t.sol | 25 +++++- test/enigma-dark-invariants/Setup.t.sol | 2 +- .../_config/echidna_config.yaml | 3 + .../base/BaseStorage.t.sol | 2 +- .../base/BaseTest.t.sol | 90 ++++++++++++++++--- .../setup/EulerSwapSetupHandler.t.sol | 35 +++++--- .../handlers/swap/EulerSwapHandler.t.sol | 4 +- .../swap/EulerSwapPeripheryHandler.t.sol | 6 +- .../invariants/BaseInvariants.t.sol | 62 ++++++++++++- .../specs/InvariantsSpec.t.sol | 37 +++++++- .../specs/PostconditionsSpec.t.sol | 7 -- .../utils/PropertiesAsserts.sol | 21 +++++ .../utils/PropertiesConstants.sol | 2 + 14 files changed, 254 insertions(+), 47 deletions(-) diff --git a/test/enigma-dark-invariants/CryticToFoundry.t.sol b/test/enigma-dark-invariants/CryticToFoundry.t.sol index 96c0476..52781bf 100644 --- a/test/enigma-dark-invariants/CryticToFoundry.t.sol +++ b/test/enigma-dark-invariants/CryticToFoundry.t.sol @@ -1,6 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; +// Interfaces +import {IEulerSwap} from "src/interfaces/IEulerSwap.sol"; + // Libraries import "forge-std/Test.sol"; import "forge-std/console.sol"; @@ -40,7 +43,7 @@ contract CryticToFoundry is Invariants, Setup { // POSTCONDITIONS REPLAY // /////////////////////////////////////////////////////////////////////////////////////////////// -/* function test_replay_swap() public { + /* function test_replay_swap() public { //@audit-issue is possible to extract value from the protocol 1 wei of value Tester.setupMaglev(10, 50e18, 50e18, 0, Curve(0), MaglevEulerSwap.EulerSwapParams(1e18, 1e18, 0.4e18, 0.85e18)); Tester.mint(2000000, 0, 0); diff --git a/test/enigma-dark-invariants/Invariants.t.sol b/test/enigma-dark-invariants/Invariants.t.sol index c55b058..7076d1c 100644 --- a/test/enigma-dark-invariants/Invariants.t.sol +++ b/test/enigma-dark-invariants/Invariants.t.sol @@ -16,8 +16,29 @@ abstract contract Invariants is BaseInvariants { // BASE INVARIANTS // /////////////////////////////////////////////////////////////////////////////////////////////// - function echidna_BASE_ASSETS_INVARIANTS() public returns (bool) { - assert_INV_BASE_A(); + function echidna_CORE_INVARIANTS() public returns (bool) { + if (address(eulerSwap) != address(0)) { + assert_INV_CORE_A(); + assert_INV_CORE_C(); + } + + return true; + } + + function echidna_STATE_INVARIANTS() public returns (bool) { + if (address(eulerSwap) != address(0)) { + assert_INV_STATE_A(); + assert_INV_STATE_B(); + assert_INV_STATE_C(); + } + + return true; + } + + function echidna_DEBT_LIMIT_INVARIANTS() public returns (bool) { + if (address(eulerSwap) != address(0)) { + assert_INV_DL_A(); + } return true; } diff --git a/test/enigma-dark-invariants/Setup.t.sol b/test/enigma-dark-invariants/Setup.t.sol index bbd0c1c..c7149ab 100644 --- a/test/enigma-dark-invariants/Setup.t.sol +++ b/test/enigma-dark-invariants/Setup.t.sol @@ -135,7 +135,7 @@ contract Setup is BaseTest { baseAssets.push(address(assetTST)); oracle.setPrice(address(assetTST), unitOfAccount, 1e18); - assetTST2 = new TestERC20("Test Token 2", "TST2", 18); // TODO change decimals + assetTST2 = new TestERC20("Test Token 2", "TST2", 6); baseAssets.push(address(assetTST2)); oracle.setPrice(address(assetTST2), unitOfAccount, 1e18); } diff --git a/test/enigma-dark-invariants/_config/echidna_config.yaml b/test/enigma-dark-invariants/_config/echidna_config.yaml index 8af47f5..099e1b3 100644 --- a/test/enigma-dark-invariants/_config/echidna_config.yaml +++ b/test/enigma-dark-invariants/_config/echidna_config.yaml @@ -53,5 +53,8 @@ maxValue: 1e+23 # 100000 eth #quiet produces (much) less verbose output quiet: false +# format: "text" or "json" +format: "text" + # concurrent workers workers: 10 diff --git a/test/enigma-dark-invariants/base/BaseStorage.t.sol b/test/enigma-dark-invariants/base/BaseStorage.t.sol index a3e2498..3bd9781 100644 --- a/test/enigma-dark-invariants/base/BaseStorage.t.sol +++ b/test/enigma-dark-invariants/base/BaseStorage.t.sol @@ -55,7 +55,7 @@ abstract contract BaseStorage { /// @notice The address that is targeted when executing an action address internal targetActor; - /// @notice The account that owns the maglev liqudity + /// @notice The account that owns the euler-swap liqudity address internal holder; address internal feeRecipient; diff --git a/test/enigma-dark-invariants/base/BaseTest.t.sol b/test/enigma-dark-invariants/base/BaseTest.t.sol index 986edf5..cd32dfd 100644 --- a/test/enigma-dark-invariants/base/BaseTest.t.sol +++ b/test/enigma-dark-invariants/base/BaseTest.t.sol @@ -8,6 +8,7 @@ import {IEulerSwap} from "src/interfaces/IEulerSwap.sol"; // Libraries import {Vm} from "forge-std/Base.sol"; import {StdUtils} from "forge-std/StdUtils.sol"; +import {Math} from "openzeppelin-contracts/utils/math/Math.sol"; // Utils import {Actor} from "../utils/Actor.sol"; @@ -142,17 +143,28 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU return int256(balValue) - int256(debtValue); } - function _createEulerSwap( // TODO should we deploy from the factory instead? - uint112 debtLimitA, uint112 debtLimitB, uint256 fee, uint256 px, uint256 py, uint256 cx, uint256 cy) - internal - { - eulerSwap = new EulerSwap( - _getEulerSwapParams(debtLimitA, debtLimitB, fee), - IEulerSwap.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) - ); - - vm.prank(holder); - evc.setAccountOperator(holder, address(eulerSwap), true); + function _createEulerSwap( + uint112 debtLimitA, + uint112 debtLimitB, + uint256 fee, + uint256 px, + uint256 py, + uint256 cx, + uint256 cy + ) internal returns (bool) { + EulerSwap.Params memory params = _getEulerSwapParams(debtLimitA, debtLimitB, fee); + IEulerSwap.CurveParams memory curveParams = + IEulerSwap.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}); + + try new EulerSwap(params, curveParams) returns (EulerSwap _eulerSwap) { + eulerSwap = _eulerSwap; + vm.prank(holder); + evc.setAccountOperator(holder, address(eulerSwap), true); + return true; + } catch (bytes memory reason) { + console.logBytes(reason); + return false; + } } function _getEulerSwapParams(uint112 reserve0, uint112 reserve1, uint256 fee) @@ -160,9 +172,11 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU view returns (EulerSwap.Params memory) { + (address vault0, address vault1) = + eTST.asset() < eTST2.asset() ? (address(eTST), address(eTST2)) : (address(eTST2), address(eTST)); return IEulerSwap.Params({ - vault0: address(eTST), - vault1: address(eTST2), + vault0: vault0, + vault1: vault1, eulerAccount: holder, equilibriumReserve0: reserve0, equilibriumReserve1: reserve1, @@ -171,4 +185,54 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU fee: fee }); } + + /// @notice Helper function to generate points that lie on the Euler curve + /// @param x The x coordinate to generate a corresponding y value for + /// @param priceX Price ratio for asset X + /// @param priceY Price ratio for asset Y + /// @param x0 Equilibrium reserve for x + /// @param y0 Equilibrium reserve for y + /// @param c Concentration parameter + /// @return y The corresponding y coordinate that lies on the curve + function _generatePointOnCurve(uint256 x, uint256 priceX, uint256 priceY, uint256 x0, uint256 y0, uint256 c) + internal + pure + returns (uint256 y) + { + // If x is above equilibrium, we're in the upper region + if (x >= x0) { + return y0; // In upper region, any y >= y0 is valid + } + // If x is below equilibrium, calculate required y using curve function + unchecked { + uint256 v = Math.mulDiv(priceX * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil); + require(v <= type(uint248).max, "Overflow"); + y = y0 + (v + (priceY - 1)) / priceY; + } + } + + /// @notice Helper function to generate balanced initial reserves that satisfy the curve + /// @param targetReserve0 Approximate target for reserve0 + /// @param targetReserve1 Approximate target for reserve1 + /// @param curveParams Curve parameters to use + /// @return reserve0 Valid reserve0 that lies on curve + /// @return reserve1 Valid reserve1 that lies on curve + function _generateBalancedReserves( + uint112 targetReserve0, + uint112 targetReserve1, + IEulerSwap.CurveParams memory curveParams + ) internal pure returns (uint112 reserve0, uint112 reserve1) { + // Start with target values as equilibrium points + uint256 x0 = targetReserve0; + uint256 y0 = targetReserve1; + + // Generate a point slightly below equilibrium + uint256 x = (x0 * 95) / 100; // 95% of equilibrium + uint256 y = _generatePointOnCurve(x, curveParams.priceX, curveParams.priceY, x0, y0, curveParams.concentrationX); + + // Ensure values fit within uint112 + require(x <= type(uint112).max && y <= type(uint112).max, "Reserves too large"); + + return (uint112(x), uint112(y)); + } } diff --git a/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol b/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol index 314e32c..209e257 100644 --- a/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol @@ -34,7 +34,9 @@ abstract contract EulerSwapSetupHandler is BaseHandler { /// --- CLAMPING PARAMETERS --- // Restrict leverage to a maximum of x10 - leverage = uint8(clampBetween(leverage, 1, 10)); + leverage = uint8(clampBetween(leverage, MIN_LEVERAGE, MAX_LEVERAGE)); + + (initialAmount0, initialAmount1) = _generateBalancedReserves(initialAmount0, initialAmount1, curveParams); // Ensure initial deposit amounts are at least 1000 tokens and within leverage limits initialAmount0 = uint112(clampBetween(initialAmount0, 1000e18, type(uint112).max / leverage)); @@ -45,13 +47,15 @@ abstract contract EulerSwapSetupHandler is BaseHandler { uint112 debtLimit1 = initialAmount1 * leverage; // Clamp price values within a reasonable range (0.1 to 10) - curveParams.priceX = clampBetween(curveParams.priceX, 0.1e18, 10e18); // TODO should this setup oracles as well? - curveParams.priceY = clampBetween(curveParams.priceY, 0.1e18, 10e18); + curveParams.priceX = clampBetween(curveParams.priceX, 0.1e16, 1e36); // TODO Integrate oracle price + curveParams.priceY = clampBetween(curveParams.priceY, 0.1e16, 1e36); // Clamp concentration between 0.1e18 and 1e18 - curveParams.concentrationX = clampBetween(curveParams.concentrationX, 0.1e18, 1e18); + curveParams.concentrationX = clampBetween(curveParams.concentrationX, 0.1e18, 1e18); // TODO Implement test variants with imbalanced initial pools where concentrationX != concentrationY and reserves don't match equilibrium values - this should verify curve behavior under asymmetric conditions curveParams.concentrationY = clampBetween(curveParams.concentrationY, 0.1e18, 1e18); + // Check equilibriumReserves are on the curve + /// --- INITIAL DEPOSITS --- // Deposit initial funds into vaults on behalf of the holder @@ -63,14 +67,17 @@ abstract contract EulerSwapSetupHandler is BaseHandler { /// --- DEPLOY EULER SWAP CONTRACT --- - _createEulerSwap( - debtLimit0, - debtLimit1, - fee, - curveParams.priceX, - curveParams.priceY, - curveParams.concentrationX, - curveParams.concentrationY + assertTrue( + _createEulerSwap( + debtLimit0, + debtLimit1, + fee, + curveParams.priceX, + curveParams.priceY, + curveParams.concentrationX, + curveParams.concentrationY + ), + "EulerSwapSetupHandler: failed to create EulerSwap" ); /// --- SETUP ACTORS' TOKEN APPROVALS --- @@ -81,4 +88,8 @@ abstract contract EulerSwapSetupHandler is BaseHandler { _setupActorApprovals(baseAssets, contracts); } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // EULER-SWAP SPECIFIC HELPERS // + /////////////////////////////////////////////////////////////////////////////////////////////// } diff --git a/test/enigma-dark-invariants/handlers/swap/EulerSwapHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/EulerSwapHandler.t.sol index 1f73509..f7e54f8 100644 --- a/test/enigma-dark-invariants/handlers/swap/EulerSwapHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/EulerSwapHandler.t.sol @@ -26,7 +26,9 @@ abstract contract EulerSwapHandler is BaseHandler { // ACTIONS // /////////////////////////////////////////////////////////////////////////////////////////////// - // TODO activate() function + function activate() public setup eulerSwapDeployed { + eulerSwap.activate(); + } function swap(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In, uint8 i) public diff --git a/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol index 73d18b2..083001e 100644 --- a/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol @@ -42,7 +42,7 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { if (success) { _after(); - // _eulerSwapPostconditions(amount0Out, amount1Out, amount0In, amount1In); // TODO check postconditions + //_eulerSwapPostconditions(amount0Out, amount1Out, amount0In, amount1In); // TODO Adapt these postconditions to periphery } else { revert("EulerSwapPeripheryHandler: swapExactIn failed"); } @@ -67,7 +67,7 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { if (success) { _after(); - // _eulerSwapPostconditions(amount0Out, amount1Out, amount0In, amount1In); // TODO check postconditions + //_eulerSwapPostconditions(amount0Out, amount1Out, amount0In, amount1In); // TODO Adapt these postconditions to periphery } else { revert("EulerSwapPeripheryHandler: swapExactOut failed"); } @@ -92,6 +92,4 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { assertTrue(false, NR_QUOTE_B); } } - - // getLimits //TODO } diff --git a/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol b/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol index 037aec5..aa8345d 100644 --- a/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol +++ b/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol @@ -16,10 +16,66 @@ import "forge-std/console.sol"; /// @dev Inherits HandlerAggregator to check actions in assertion testing mode abstract contract BaseInvariants is HandlerAggregator { /////////////////////////////////////////////////////////////////////////////////////////////// - // BASE // + // CORE // /////////////////////////////////////////////////////////////////////////////////////////////// - function assert_INV_BASE_A() internal { - assertFalse(eTST.debtOf(holder) != 0 && eTST2.debtOf(holder) != 0, INV_BASE_A); + function assert_INV_CORE_A() internal { + assertFalse(eTST.debtOf(holder) != 0 && eTST2.debtOf(holder) != 0, INV_CORE_A); + } + + function assert_INV_CORE_B() internal { + address[] memory controllers = evc.getControllers(); + + address controller = controllers[0]; + + (uint256 collateralValue, uint256 liabilityValue) = + IEVault(controller).accountLiquidity(eulerSwap.eulerAccount(), false); + + assertTrue(collateralValue >= liabilityValue, INV_CORE_B); + } + + function assert_INV_CORE_C() internal { + // The curve invariant must always hold + (uint112 reserve0, uint112 reserve1,) = eulerSwap.getReserves(); + assertTrue(eulerSwap.verify(reserve0, reserve1), INV_CORE_C); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // STATE MANAGEMENT // + /////////////////////////////////////////////////////////////////////////////////////////////// + + function assert_INV_STATE_A() internal { + (,, uint32 status) = eulerSwap.getReserves(); + + assertTrue(status == 0 || status == 1 || status == 2, INV_STATE_A); + } + + function assert_INV_STATE_B() internal { + assertTrue(eulerSwap.asset0() < eulerSwap.asset1(), INV_STATE_B); + } + + function assert_INV_STATE_C() internal { + // Controller should be properly enabled/disabled + bool controller0 = evc.isControllerEnabled(eulerSwap.eulerAccount(), address(eTST)); + bool controller1 = evc.isControllerEnabled(eulerSwap.eulerAccount(), address(eTST2)); + + // If there's debt, controller should be enabled + assertTrue( + (eTST.debtOf(eulerSwap.eulerAccount()) == 0 || controller0) + && (eTST2.debtOf(eulerSwap.eulerAccount()) == 0 || controller1), + INV_STATE_C + ); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // DEBT LIMIT // + /////////////////////////////////////////////////////////////////////////////////////////////// + function assert_INV_DL_A() internal { + // Total borrowed amount should never exceed leverage * initial reserves + uint256 totalDebt0 = eTST.debtOf(eulerSwap.eulerAccount()); + uint256 totalDebt1 = eTST2.debtOf(eulerSwap.eulerAccount()); + + assertLe(totalDebt0, uint256(eulerSwap.equilibriumReserve0()) * MAX_LEVERAGE, INV_DL_A); + assertLe(totalDebt1, uint256(eulerSwap.equilibriumReserve1()) * MAX_LEVERAGE, INV_DL_A); } } diff --git a/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol b/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol index 2e2666e..17b6068 100644 --- a/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol +++ b/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol @@ -16,8 +16,41 @@ abstract contract InvariantsSpec { /////////////////////////////////////////////////////////////////////////////////////////////*/ /////////////////////////////////////////////////////////////////////////////////////////////// - // BASE // + // CORE // /////////////////////////////////////////////////////////////////////////////////////////////// - string constant INV_BASE_A = "INV_BASE_A: At most one of vault0 or vault1 has debt (unless the CDP is under water)"; + string constant INV_CORE_A = "INV_CORE_A: At most one of vault0 or vault1 has debt (unless the CDP is under water)"; + + string constant INV_CORE_B = "INV_CORE_B: Account should never be liquidatable"; + + string constant INV_CORE_C = "INV_CORE_C: The curve invariant must always hold"; + + /////////////////////////////////////////////////////////////////////////////////////////////// + // STATE MANAGEMENT // + /////////////////////////////////////////////////////////////////////////////////////////////// + + string constant INV_STATE_A = "INV_STATE_A: Status should only transition in valid ways"; + + string constant INV_STATE_B = "INV_STATE_B: Asset addresses should maintain correct ordering"; + + string constant INV_STATE_C = "INV_STATE_C: If there's debt, controller should be enabled"; + + /////////////////////////////////////////////////////////////////////////////////////////////// + // DEBT LIMIT // + /////////////////////////////////////////////////////////////////////////////////////////////// + + string constant INV_DL_A = "INV_DL_A: Leverage should not exceed debt limits"; + + string constant INV_DL_B = "INV_DL_B: Total borrowed amount should never exceed leverage * initial reserves"; // TODO + + // TODO: Implement invariants based on ChainSecurity report formulas + // TODO: Implement invariants for LTV checks from ChainSecurity report + // TODO: Implement invariants for liquidation checks from ChainSecurity report + // TODO: Implement invariants for reserve desynchronization from ChainSecurity report + // TODO: Implement invariant to ensure debt never exceeds the debt limit + // TODO: Implement invariants from the team call notes + // TODO: Review the trust model of the protocol as outlined in the ChainSecurity report + // TODO: Review the binary search implementation + // TODO: Implement check for rounding error amplification (5.5) + // TODO: Implement check to prevent Donation Attack resulting in DoS (5.1), ensuring the "quote" rule makes swap always succeed } diff --git a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol index aafddba..456610f 100644 --- a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol +++ b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol @@ -43,11 +43,4 @@ abstract contract PostconditionsSpec { string constant HSPOST_RESERVES_C = "HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed"; - - - // TODO - // - if it has debt it shouldnt have balance - /* - - donations should only increase nav or reduce leverage - */ } diff --git a/test/enigma-dark-invariants/utils/PropertiesAsserts.sol b/test/enigma-dark-invariants/utils/PropertiesAsserts.sol index 6d0fcc1..b60a54e 100644 --- a/test/enigma-dark-invariants/utils/PropertiesAsserts.sol +++ b/test/enigma-dark-invariants/utils/PropertiesAsserts.sol @@ -215,6 +215,27 @@ abstract contract PropertiesAsserts { return value; } + /// @notice Clamps value to be between low and high, exclusively (not including boundary points) + function clampBetweenExclusive(uint256 value, uint256 low, uint256 high) internal pure returns (uint256) {/// @dev + require(high > low + 1, "Invalid range: must have at least one value between low and high"); + if (value <= low || value >= high) { + return low + 1 + (value % (high - low - 1)); + } + return value; + } + + /// @notice int256 version of clampBetweenExclusive + function clampBetweenExclusive(int256 value, int256 low, int256 high) internal pure returns (int256) { + require(high > low + 1, "Invalid range: must have at least one value between low and high"); + if (value <= low || value >= high) { + int256 range = high - low - 1; + int256 clamped = (value - (low + 1)) % range; + if (clamped < 0) clamped += range; + return low + 1 + clamped; + } + return value; + } + /// @notice clamps a to be less than b function clampLt(uint256 a, uint256 b) internal returns (uint256) { if (!(a < b)) { diff --git a/test/enigma-dark-invariants/utils/PropertiesConstants.sol b/test/enigma-dark-invariants/utils/PropertiesConstants.sol index cfea635..9ffde57 100644 --- a/test/enigma-dark-invariants/utils/PropertiesConstants.sol +++ b/test/enigma-dark-invariants/utils/PropertiesConstants.sol @@ -8,4 +8,6 @@ abstract contract PropertiesConstants { address constant USER3 = address(0x30000); uint256 constant INITIAL_BALANCE = 1000e30; uint256 constant INTEREST_SMEAR = 2 weeks; + uint256 constant MAX_LEVERAGE = 10; + uint256 constant MIN_LEVERAGE = 1; } From 2c75d671a55157c08c60737697549cd132e94001 Mon Sep 17 00:00:00 2001 From: Elpacos Date: Thu, 27 Mar 2025 20:29:12 +0100 Subject: [PATCH 15/18] chore: add improvements and replays --- .../CryticToFoundry.t.sol | 45 +++++++++ test/enigma-dark-invariants/Setup.t.sol | 25 +++-- .../base/BaseHandler.t.sol | 94 ++++++++++++++++++- .../base/BaseTest.t.sol | 55 ++++++++++- .../setup/EulerSwapSetupHandler.t.sol | 9 +- .../simulators/PriceOracleHandler.t.sol | 2 +- .../handlers/swap/EulerSwapHandler.t.sol | 71 +------------- .../swap/EulerSwapPeripheryHandler.t.sol | 24 ++++- .../invariants/BaseInvariants.t.sol | 5 +- .../specs/InvariantsSpec.t.sol | 19 ++-- .../specs/PostconditionsSpec.t.sol | 6 ++ .../utils/PropertiesConstants.sol | 8 +- 12 files changed, 260 insertions(+), 103 deletions(-) diff --git a/test/enigma-dark-invariants/CryticToFoundry.t.sol b/test/enigma-dark-invariants/CryticToFoundry.t.sol index 52781bf..9546c46 100644 --- a/test/enigma-dark-invariants/CryticToFoundry.t.sol +++ b/test/enigma-dark-invariants/CryticToFoundry.t.sol @@ -71,6 +71,51 @@ contract CryticToFoundry is Invariants, Setup { Tester.roundtripSwap(200000000, 0); } */ + function test_replay_setupEulerSwap() public { + //@audit-ok fixed by clamping fee + Tester.setupEulerSwap( + 0, + 0, + 0, + 1003720677821071739, + IEulerSwap.CurveParams( + 0, 12246676942863640986141097041882032371945, 31951643412123143093714293698540253070340823296393767, 0 + ) + ); + } + + function test_replay_swapExactOut() public { + //@audit Invalid: 1!=0, reason: HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed + Tester.setupEulerSwap(0, 0, 0, 0, IEulerSwap.CurveParams(0, 0, 0, 0)); + Tester.swap(0, 0, 1, 0, 0); + Tester.mint(1, 1, 0); + Tester.redeem(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 0); + Tester.swapExactOut(0, 0, false); + } + + function test_replay_roundtripSwap() public { + //@audit Invalid: 1999999999999999999999<2000000000000000000000 failed, reason: HSPOST_SWAP_A: Holder's NAV should increase monotonically + Tester.setupEulerSwap(0, 0, 0, 0, IEulerSwap.CurveParams(2069895513206400, 0, 0, 77696590)); + Tester.roundtripSwap(1, 0); + } + + function test_replay_swap() public { + //@audit Invalid: 1!=0, reason: HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed + Tester.setupEulerSwap(0, 0, 0, 0, IEulerSwap.CurveParams(0, 0, 0, 0)); + Tester.redeem(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 1); + Tester.mint(1, 1, 1); + Tester.swap(0, 1, 2, 0, 0); + } + + function test_replay_swapExactIn() public { + //@audit Invalid: 1!=0, reason: HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed + Tester.setupEulerSwap(0, 0, 0, 0, IEulerSwap.CurveParams(0, 0, 0, 0)); + Tester.mint(1, 1, 0); + Tester.redeem(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 0); + Tester.donateUnderlying(2, 1); + Tester.swapExactIn(0, 0, true); + } + /////////////////////////////////////////////////////////////////////////////////////////////// // INVARIANTS REPLAY // /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/Setup.t.sol b/test/enigma-dark-invariants/Setup.t.sol index c7149ab..285a00b 100644 --- a/test/enigma-dark-invariants/Setup.t.sol +++ b/test/enigma-dark-invariants/Setup.t.sol @@ -116,6 +116,20 @@ contract Setup is BaseTest { eTST2 = _deployEVault(address(assetTST2)); vaults.push(address(eTST2)); + + // Set LTVs + eTST.setLTV(address(eTST2), BORROW_LTV, LIQUIDATION_LTV, 0); + eTST2.setLTV(address(eTST), BORROW_LTV, LIQUIDATION_LTV, 0); + + // Set pricing + oracle.setPrice(address(assetTST), unitOfAccount, 1e18); + oracle.setPrice(address(assetTST2), unitOfAccount, 1e18); + + oracle.setPrice(address(assetTST), unitOfAccount, 1e18); + oracle.setPrice(address(assetTST2), unitOfAccount, 1e18); + + oracle.setPrice(address(assetTST), address(assetTST2), 1e18); + oracle.setPrice(address(assetTST2), address(assetTST), 1e18); } function _deployEVault(address asset) internal returns (IEVault eVault) { @@ -125,19 +139,18 @@ contract Setup is BaseTest { // Configure the vault eVault.setHookConfig(address(0), 0); eVault.setInterestRateModel(address(new IRMTestDefault())); - eVault.setMaxLiquidationDiscount(0.2e4); + eVault.setMaxLiquidationDiscount(MAX_LIQUIDATION_DISCOUNT); eVault.setFeeReceiver(feeRecipient); } function _deployAssets() internal { // Deploy base assets - assetTST = new TestERC20("Test Token", "TST", 18); - baseAssets.push(address(assetTST)); - oracle.setPrice(address(assetTST), unitOfAccount, 1e18); + TestERC20 asset0 = new TestERC20("Test Token", "TST", 18); + TestERC20 asset1 = new TestERC20("Test Token 2", "TST2", 6); + (assetTST, assetTST2) = (address(asset0) < address(asset1) ? (asset0, asset1) : (asset1, asset0)); - assetTST2 = new TestERC20("Test Token 2", "TST2", 6); + baseAssets.push(address(assetTST)); baseAssets.push(address(assetTST2)); - oracle.setPrice(address(assetTST2), unitOfAccount, 1e18); } /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/base/BaseHandler.t.sol b/test/enigma-dark-invariants/base/BaseHandler.t.sol index 9af4cd0..e0bd730 100644 --- a/test/enigma-dark-invariants/base/BaseHandler.t.sol +++ b/test/enigma-dark-invariants/base/BaseHandler.t.sol @@ -18,6 +18,12 @@ import {HookAggregator} from "../hooks/HookAggregator.t.sol"; contract BaseHandler is HookAggregator { using EnumerableSet for EnumerableSet.UintSet; + /////////////////////////////////////////////////////////////////////////////////////////////// + // STATE VARIABLES // + /////////////////////////////////////////////////////////////////////////////////////////////// + + address receiver; + /////////////////////////////////////////////////////////////////////////////////////////////// // MODIFIERS // /////////////////////////////////////////////////////////////////////////////////////////////// @@ -69,8 +75,10 @@ contract BaseHandler is HookAggregator { return vaults[_vaultIndex]; } - function _getAssetsByDir(bool dir) internal view returns (address assetIn, address assetOut) { - return dir ? (address(assetTST), address(assetTST2)) : (address(assetTST2), address(assetTST)); + function _getAssetsByDir(bool dir) internal view returns (address asset0, address asset1) { + asset0 = eulerSwap.asset0(); + asset1 = eulerSwap.asset1(); + return dir ? (asset0, asset1) : (asset1, asset0); } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -89,8 +97,8 @@ contract BaseHandler is HookAggregator { } /// @notice Helper function to mint an amount of tokens to an address - function _mint(address token, address receiver, uint256 amount) internal { - TestERC20(token).mint(receiver, amount); + function _mint(address token, address receiver_, uint256 amount) internal { + TestERC20(token).mint(receiver_, amount); } /// @notice Helper function to mint an amount of tokens to an address and approve them to a spender @@ -102,4 +110,82 @@ contract BaseHandler is HookAggregator { _mint(token, owner, amount); _approve(token, owner, spender, amount); } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // HSPOST: SWAP // + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// @notice Postconditions common to all three curves + function _eulerSwapPostconditions( + uint256 amount0Out, + uint256 amount1Out, + uint256 amount0In, + uint256 amount1In + ) internal { + /// @dev HSPOST_SWAP_C + + if (amount0Out > 0) { + assertEq( + defaultVarsAfter.users[receiver].assetTSTBalance, + defaultVarsBefore.users[receiver].assetTSTBalance + amount0Out, + HSPOST_SWAP_C + ); + } + + if (amount1Out > 0) { + assertEq( + defaultVarsAfter.users[receiver].assetTST2Balance, + defaultVarsBefore.users[receiver].assetTST2Balance + amount1Out, + HSPOST_SWAP_C + ); + } + + /// @dev HSPOST_SWAP_A + + assertGe(defaultVarsAfter.holderNAV, defaultVarsBefore.holderNAV, HSPOST_SWAP_A); + + /// @dev HSPOST_RESERVES_A + + if (amount0In < defaultVarsBefore.holderETSTDebt) { + assertEq(defaultVarsAfter.holderETSTDebt, defaultVarsBefore.holderETSTDebt - amount0In, HSPOST_SWAP_B); + } else { + assertEq(defaultVarsAfter.holderETSTDebt, 0, HSPOST_RESERVES_A); + } + + if (amount1In < defaultVarsBefore.holderETST2Debt) { + assertEq(defaultVarsAfter.holderETST2Debt, defaultVarsBefore.holderETST2Debt - amount1In, HSPOST_SWAP_B); + } else { + assertEq(defaultVarsAfter.holderETST2Debt, 0, HSPOST_RESERVES_A); + } + + /// @dev HSPOST_RESERVES_B + + if (amount0Out < defaultVarsBefore.holderETSTAssets) { + assertEq( + defaultVarsAfter.holderETSTAssets, defaultVarsBefore.holderETSTAssets - amount0Out, HSPOST_RESERVES_B + ); + } else { + assertEq(defaultVarsAfter.holderETSTAssets, 0, HSPOST_RESERVES_B); + assertEq( + defaultVarsAfter.holderETSTDebt, amount0Out - defaultVarsBefore.holderETSTAssets, HSPOST_RESERVES_C + ); + } + + if (amount1Out < defaultVarsBefore.holderETST2Assets) { + assertEq( + defaultVarsAfter.holderETST2Assets, defaultVarsBefore.holderETST2Assets - amount1Out, HSPOST_RESERVES_B + ); + } else { + assertEq(defaultVarsAfter.holderETST2Assets, 0, HSPOST_RESERVES_B); + assertEq( + defaultVarsAfter.holderETST2Debt, amount1Out - defaultVarsBefore.holderETST2Assets, HSPOST_RESERVES_C + ); + } + + /// @dev HSPOST_DEBT_A + assertLe(defaultVarsAfter.holderETSTDebt, eulerSwap.reserve0(), HSPOST_DEBT_A); + assertLe(defaultVarsAfter.holderETST2Debt, eulerSwap.reserve1(), HSPOST_DEBT_A); + assertLe(defaultVarsAfter.holderETSTDebt, eulerSwap.reserve1(), HSPOST_DEBT_A); + assertLe(defaultVarsAfter.holderETST2Debt, eulerSwap.reserve0(), HSPOST_DEBT_A); + } } diff --git a/test/enigma-dark-invariants/base/BaseTest.t.sol b/test/enigma-dark-invariants/base/BaseTest.t.sol index cd32dfd..71076c3 100644 --- a/test/enigma-dark-invariants/base/BaseTest.t.sol +++ b/test/enigma-dark-invariants/base/BaseTest.t.sol @@ -41,9 +41,9 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU targetActor = address(0); } - /// @dev Solves medusa backward time warp issue - modifier monotonicTimestamp() virtual { - // Implement monotonic timestamp if needed + /// @dev Skim euler swap assets + modifier skimAll() virtual { + _skimAll(eulerSwap, true); _; } @@ -129,6 +129,50 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU // EULER-SWAP SPECIFIC HELPERS // /////////////////////////////////////////////////////////////////////////////////////////////// + function _skimAll(EulerSwap ml, bool order) internal { + if (order) { + _runSkimAll(ml, true); + _runSkimAll(ml, false); + } else { + _runSkimAll(ml, false); + _runSkimAll(ml, true); + } + } + + function _runSkimAll(EulerSwap ml, bool dir) internal returns (uint256) { + uint256 skimmed = 0; + uint256 val = 1; + + // Phase 1: Keep doubling skim amount until it fails + + while (true) { + (uint256 amount0, uint256 amount1) = dir ? (val, uint256(0)) : (uint256(0), val); + + try ml.swap(amount0, amount1, address(0xDEAD), "") { + skimmed += val; + val *= 2; + } catch { + break; + } + } + + // Phase 2: Keep halving skim amount until 1 wei skim fails + + while (true) { + if (val > 1) val /= 2; + + (uint256 amount0, uint256 amount1) = dir ? (val, uint256(0)) : (uint256(0), val); + + try ml.swap(amount0, amount1, address(0xDEAD), "") { + skimmed += val; + } catch { + if (val == 1) break; + } + } + + return skimmed; + } + function _getHolderNAV() internal view returns (int256) { uint256 balance0 = eTST.convertToAssets(eTST.balanceOf(holder)); uint256 debt0 = eTST.debtOf(holder); @@ -153,6 +197,7 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU uint256 cy ) internal returns (bool) { EulerSwap.Params memory params = _getEulerSwapParams(debtLimitA, debtLimitB, fee); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}); @@ -172,8 +217,8 @@ abstract contract BaseTest is BaseStorage, PropertiesConstants, StdAsserts, StdU view returns (EulerSwap.Params memory) { - (address vault0, address vault1) = - eTST.asset() < eTST2.asset() ? (address(eTST), address(eTST2)) : (address(eTST2), address(eTST)); + (address vault0, address vault1) = (address(eTST), address(eTST2)); + return IEulerSwap.Params({ vault0: vault0, vault1: vault1, diff --git a/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol b/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol index 209e257..59697dd 100644 --- a/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol @@ -33,6 +33,9 @@ abstract contract EulerSwapSetupHandler is BaseHandler { ) public eulerSwapNotDeployed { /// --- CLAMPING PARAMETERS --- + // Clamp fee to a maximum of 1e18 + fee = clampBetween(fee, 0, 1e18); + // Restrict leverage to a maximum of x10 leverage = uint8(clampBetween(leverage, MIN_LEVERAGE, MAX_LEVERAGE)); @@ -47,11 +50,11 @@ abstract contract EulerSwapSetupHandler is BaseHandler { uint112 debtLimit1 = initialAmount1 * leverage; // Clamp price values within a reasonable range (0.1 to 10) - curveParams.priceX = clampBetween(curveParams.priceX, 0.1e16, 1e36); // TODO Integrate oracle price + curveParams.priceX = clampBetween(curveParams.priceX, 0.1e16, 1e36); curveParams.priceY = clampBetween(curveParams.priceY, 0.1e16, 1e36); // Clamp concentration between 0.1e18 and 1e18 - curveParams.concentrationX = clampBetween(curveParams.concentrationX, 0.1e18, 1e18); // TODO Implement test variants with imbalanced initial pools where concentrationX != concentrationY and reserves don't match equilibrium values - this should verify curve behavior under asymmetric conditions + curveParams.concentrationX = clampBetween(curveParams.concentrationX, 0.1e18, 1e18); // TODO Implement test variants with imbalanced initial pools, reserves don't match equilibrium values - this should verify curve behavior under asymmetric conditions curveParams.concentrationY = clampBetween(curveParams.concentrationY, 0.1e18, 1e18); // Check equilibriumReserves are on the curve @@ -80,6 +83,8 @@ abstract contract EulerSwapSetupHandler is BaseHandler { "EulerSwapSetupHandler: failed to create EulerSwap" ); + assertTrue(eulerSwap.asset0() == address(assetTST), "EulerSwapSetupHandler: asset0 is not assetTST"); + assertTrue(eulerSwap.asset1() == address(assetTST2), "EulerSwapSetupHandler: asset1 is not assetTST2"); /// --- SETUP ACTORS' TOKEN APPROVALS --- // Configure actors' token approvals for the eulerSwap contract diff --git a/test/enigma-dark-invariants/handlers/simulators/PriceOracleHandler.t.sol b/test/enigma-dark-invariants/handlers/simulators/PriceOracleHandler.t.sol index 2776c09..cc013ba 100644 --- a/test/enigma-dark-invariants/handlers/simulators/PriceOracleHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/simulators/PriceOracleHandler.t.sol @@ -22,7 +22,7 @@ abstract contract PriceOracleHandler is BaseHandler { function setPrice(uint8 i, uint256 price) external { address baseAsset = _getRandomBaseAsset(i); - oracle.setPrice(baseAsset, unitOfAccount, price); + //oracle.setPrice(baseAsset, unitOfAccount, price); TODO implement subtile variations } /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/handlers/swap/EulerSwapHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/EulerSwapHandler.t.sol index f7e54f8..8cb4011 100644 --- a/test/enigma-dark-invariants/handlers/swap/EulerSwapHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/EulerSwapHandler.t.sol @@ -20,7 +20,6 @@ abstract contract EulerSwapHandler is BaseHandler { /////////////////////////////////////////////////////////////////////////////////////////////// address roundtripSwapActor; - address receiver; /////////////////////////////////////////////////////////////////////////////////////////////// // ACTIONS // @@ -34,6 +33,7 @@ abstract contract EulerSwapHandler is BaseHandler { public setup eulerSwapDeployed + skimAll { bool success; bytes memory returnData; @@ -116,74 +116,7 @@ abstract contract EulerSwapHandler is BaseHandler { uint256 actorInBalanceAfter = assetTSTIn.balanceOf(roundtripSwapActor); - // HSPOST + /// @dev HSPOST_SWAP_B assertLe(actorInBalanceAfter, actorInBalanceBefore, HSPOST_SWAP_B); } - - /////////////////////////////////////////////////////////////////////////////////////////////// - // HSPOST: SWAP // - /////////////////////////////////////////////////////////////////////////////////////////////// - - /// @notice Postconditions common to all three curves - function _eulerSwapPostconditions(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In) - internal - { - /// @dev HSPOST_SWAP_C - - if (amount0Out > 0) { - assertEq( - defaultVarsAfter.users[receiver].assetTSTBalance, - defaultVarsBefore.users[receiver].assetTSTBalance + amount0Out, - HSPOST_SWAP_C - ); - } - - if (amount1Out > 0) { - assertEq( - defaultVarsAfter.users[receiver].assetTST2Balance, - defaultVarsBefore.users[receiver].assetTST2Balance + amount1Out, - HSPOST_SWAP_C - ); - } - - //assertGe(defaultVarsAfter.holderNAV, defaultVarsBefore.holderNAV, HSPOST_SWAP_A); - - /// @dev HSPOST_RESERVES_A - - if (amount0In < defaultVarsBefore.holderETSTDebt) { - assertEq(defaultVarsAfter.holderETSTDebt, defaultVarsBefore.holderETSTDebt - amount0In, HSPOST_SWAP_B); - } else { - assertEq(defaultVarsAfter.holderETSTDebt, 0, HSPOST_RESERVES_A); - } - - if (amount1In < defaultVarsBefore.holderETST2Debt) { - assertEq(defaultVarsAfter.holderETST2Debt, defaultVarsBefore.holderETST2Debt - amount1In, HSPOST_SWAP_B); - } else { - assertEq(defaultVarsAfter.holderETST2Debt, 0, HSPOST_RESERVES_A); - } - - /// @dev HSPOST_RESERVES_B - - if (amount0Out < defaultVarsBefore.holderETSTAssets) { - assertEq( - defaultVarsAfter.holderETSTAssets, defaultVarsBefore.holderETSTAssets - amount0Out, HSPOST_RESERVES_B - ); - } else { - assertEq(defaultVarsAfter.holderETSTAssets, 0, HSPOST_RESERVES_B); - assertEq( - defaultVarsAfter.holderETSTDebt, amount0Out - defaultVarsBefore.holderETSTAssets, HSPOST_RESERVES_C - ); - } - - if (amount1Out < defaultVarsBefore.holderETST2Assets) { - assertEq( - defaultVarsAfter.holderETST2Assets, defaultVarsBefore.holderETST2Assets - amount1Out, HSPOST_RESERVES_B - ); - } else { - assertEq(defaultVarsAfter.holderETST2Assets, 0, HSPOST_RESERVES_B); - assertEq( - defaultVarsAfter.holderETST2Debt, amount1Out - defaultVarsBefore.holderETST2Assets, HSPOST_RESERVES_C - ); - } - } } diff --git a/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol index 083001e..38122cb 100644 --- a/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol @@ -23,10 +23,12 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { // ACTIONS // /////////////////////////////////////////////////////////////////////////////////////////////// - function swapExactIn(uint256 amountIn, uint256 amountOutMin, bool dir) public setup eulerSwapDeployed { + function swapExactIn(uint256 amountIn, uint256 amountOutMin, bool dir) public setup eulerSwapDeployed skimAll { bool success; bytes memory returnData; + receiver = address(actor); + address target = address(periphery); (address tokenIn, address tokenOut) = _getAssetsByDir(dir); @@ -42,16 +44,24 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { if (success) { _after(); - //_eulerSwapPostconditions(amount0Out, amount1Out, amount0In, amount1In); // TODO Adapt these postconditions to periphery + if (dir) { + _eulerSwapPostconditions(0, amountOutMin, amountIn, 0); + } else { + _eulerSwapPostconditions(amountOutMin, 0, 0, amountIn); + } } else { revert("EulerSwapPeripheryHandler: swapExactIn failed"); } + + delete receiver; } - function swapExactOut(uint256 amountOut, uint256 amountInMax, bool dir) public setup eulerSwapDeployed { + function swapExactOut(uint256 amountOut, uint256 amountInMax, bool dir) public setup eulerSwapDeployed skimAll { bool success; bytes memory returnData; + receiver = address(actor); + address target = address(periphery); (address tokenIn, address tokenOut) = _getAssetsByDir(dir); @@ -67,10 +77,16 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { if (success) { _after(); - //_eulerSwapPostconditions(amount0Out, amount1Out, amount0In, amount1In); // TODO Adapt these postconditions to periphery + if (dir) { + _eulerSwapPostconditions(0, amountOut, amountInMax, 0); + } else { + _eulerSwapPostconditions(amountOut, 0, 0, amountInMax); + } } else { revert("EulerSwapPeripheryHandler: swapExactOut failed"); } + + delete receiver; } function quoteExactInput(uint256 amountIn, bool dir) external eulerSwapDeployed { diff --git a/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol b/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol index aa8345d..a345675 100644 --- a/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol +++ b/test/enigma-dark-invariants/invariants/BaseInvariants.t.sol @@ -5,6 +5,7 @@ pragma solidity ^0.8.19; // Interfaces import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; // Contracts import {HandlerAggregator} from "../HandlerAggregator.t.sol"; @@ -24,14 +25,14 @@ abstract contract BaseInvariants is HandlerAggregator { } function assert_INV_CORE_B() internal { - address[] memory controllers = evc.getControllers(); + address[] memory controllers = evc.getControllers(holder); address controller = controllers[0]; (uint256 collateralValue, uint256 liabilityValue) = IEVault(controller).accountLiquidity(eulerSwap.eulerAccount(), false); - assertTrue(collateralValue >= liabilityValue, INV_CORE_B); + assertTrue(collateralValue > liabilityValue, INV_CORE_B); } function assert_INV_CORE_C() internal { diff --git a/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol b/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol index 17b6068..d7b9c3c 100644 --- a/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol +++ b/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol @@ -44,13 +44,14 @@ abstract contract InvariantsSpec { string constant INV_DL_B = "INV_DL_B: Total borrowed amount should never exceed leverage * initial reserves"; // TODO // TODO: Implement invariants based on ChainSecurity report formulas - // TODO: Implement invariants for LTV checks from ChainSecurity report - // TODO: Implement invariants for liquidation checks from ChainSecurity report - // TODO: Implement invariants for reserve desynchronization from ChainSecurity report - // TODO: Implement invariant to ensure debt never exceeds the debt limit - // TODO: Implement invariants from the team call notes - // TODO: Review the trust model of the protocol as outlined in the ChainSecurity report - // TODO: Review the binary search implementation - // TODO: Implement check for rounding error amplification (5.5) - // TODO: Implement check to prevent Donation Attack resulting in DoS (5.1), ensuring the "quote" rule makes swap always succeed + // TODO: Implement invariants for LTV checks from ChainSecurity report -> no implemented, checked with liquidation invariant + // TODO: Implement invariants for liquidation checks from ChainSecurity report -> X + // TODO: Implement invariants for reserve desynchronization from ChainSecurity report -> NO + // TODO: Implement invariant to ensure debt never exceeds the debt limit -> X + // TODO: Implement invariants from the team call notes -> TODO + // TODO: Review the trust model of the protocol as outlined in the ChainSecurity report -> TODO + // TODO: Review the binary search implementation -> TODO + // TODO: Implement check for rounding error amplification (5.5) -> TODO + // TODO: Implement check to prevent Donation Attack resulting in DoS (5.1), ensuring the "quote" rule makes swap always succeed -> TODO + // TODO: Implement invariant for relation between f and f inverse -> TODO } diff --git a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol index 456610f..14de72f 100644 --- a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol +++ b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol @@ -43,4 +43,10 @@ abstract contract PostconditionsSpec { string constant HSPOST_RESERVES_C = "HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed"; + + /////////////////////////////////////////////////////////////////////////////////////////////// + // DEBT // + /////////////////////////////////////////////////////////////////////////////////////////////// + + string constant HSPOST_DEBT_A = "HSPOST_DEBT_A: Debt on an asset should never exceed the debt limit"; } diff --git a/test/enigma-dark-invariants/utils/PropertiesConstants.sol b/test/enigma-dark-invariants/utils/PropertiesConstants.sol index 9ffde57..f986436 100644 --- a/test/enigma-dark-invariants/utils/PropertiesConstants.sol +++ b/test/enigma-dark-invariants/utils/PropertiesConstants.sol @@ -7,7 +7,13 @@ abstract contract PropertiesConstants { address constant USER2 = address(0x20000); address constant USER3 = address(0x30000); uint256 constant INITIAL_BALANCE = 1000e30; - uint256 constant INTEREST_SMEAR = 2 weeks; + + // EulerSwap constants uint256 constant MAX_LEVERAGE = 10; uint256 constant MIN_LEVERAGE = 1; + + // EVault constants + uint16 constant MAX_LIQUIDATION_DISCOUNT = 0.2e4; + uint16 constant LIQUIDATION_LTV = 0.9e4; + uint16 constant BORROW_LTV = 0.9e4; } From f4f24d339d3a7fd46718dd717101f33830dce537 Mon Sep 17 00:00:00 2001 From: Elpacos Date: Fri, 28 Mar 2025 21:17:03 +0100 Subject: [PATCH 16/18] chore: add non-revert assertions --- .../base/BaseHandler.t.sol | 9 +- .../setup/EulerSwapSetupHandler.t.sol | 2 +- .../swap/EulerSwapPeripheryHandler.t.sol | 85 +++++++++++++++---- .../specs/InvariantsSpec.t.sol | 2 +- .../specs/PostconditionsSpec.t.sol | 4 + .../utils/PropertiesAsserts.sol | 3 +- 6 files changed, 80 insertions(+), 25 deletions(-) diff --git a/test/enigma-dark-invariants/base/BaseHandler.t.sol b/test/enigma-dark-invariants/base/BaseHandler.t.sol index e0bd730..8e55766 100644 --- a/test/enigma-dark-invariants/base/BaseHandler.t.sol +++ b/test/enigma-dark-invariants/base/BaseHandler.t.sol @@ -116,12 +116,9 @@ contract BaseHandler is HookAggregator { /////////////////////////////////////////////////////////////////////////////////////////////// /// @notice Postconditions common to all three curves - function _eulerSwapPostconditions( - uint256 amount0Out, - uint256 amount1Out, - uint256 amount0In, - uint256 amount1In - ) internal { + function _eulerSwapPostconditions(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In) + internal + { /// @dev HSPOST_SWAP_C if (amount0Out > 0) { diff --git a/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol b/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol index 59697dd..04e4321 100644 --- a/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/setup/EulerSwapSetupHandler.t.sol @@ -49,7 +49,7 @@ abstract contract EulerSwapSetupHandler is BaseHandler { uint112 debtLimit0 = initialAmount0 * leverage; uint112 debtLimit1 = initialAmount1 * leverage; - // Clamp price values within a reasonable range (0.1 to 10) + // Clamp price values within a reasonable range curveParams.priceX = clampBetween(curveParams.priceX, 0.1e16, 1e36); curveParams.priceY = clampBetween(curveParams.priceY, 0.1e16, 1e36); diff --git a/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol index 38122cb..3654442 100644 --- a/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol @@ -25,16 +25,15 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { function swapExactIn(uint256 amountIn, uint256 amountOutMin, bool dir) public setup eulerSwapDeployed skimAll { bool success; - bytes memory returnData; - receiver = address(actor); - address target = address(periphery); - (address tokenIn, address tokenOut) = _getAssetsByDir(dir); + (uint256 tokenInLimit, uint256 tokenOutLimit) = periphery.getLimits(address(eulerSwap), tokenIn, tokenOut); + + address target = address(periphery); _before(); - (success, returnData) = actor.proxy( + (success,) = actor.proxy( target, abi.encodeWithSelector( IEulerSwapPeriphery.swapExactIn.selector, address(eulerSwap), tokenIn, tokenOut, amountIn, amountOutMin @@ -49,6 +48,10 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { } else { _eulerSwapPostconditions(amountOutMin, 0, 0, amountIn); } + + // HSPOST + assertGt(amountIn, tokenInLimit, HSPOST_SWAP_D); + assertLt(amountOutMin, tokenOutLimit, HSPOST_SWAP_D); } else { revert("EulerSwapPeripheryHandler: swapExactIn failed"); } @@ -58,16 +61,15 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { function swapExactOut(uint256 amountOut, uint256 amountInMax, bool dir) public setup eulerSwapDeployed skimAll { bool success; - bytes memory returnData; - receiver = address(actor); - address target = address(periphery); - (address tokenIn, address tokenOut) = _getAssetsByDir(dir); + (uint256 tokenInLimit, uint256 tokenOutLimit) = periphery.getLimits(address(eulerSwap), tokenIn, tokenOut); + + address target = address(periphery); _before(); - (success, returnData) = actor.proxy( + (success,) = actor.proxy( target, abi.encodeWithSelector( IEulerSwapPeriphery.swapExactOut.selector, address(eulerSwap), tokenIn, tokenOut, amountOut, amountInMax @@ -82,6 +84,10 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { } else { _eulerSwapPostconditions(amountOut, 0, 0, amountInMax); } + + // HSPOST + assertGt(amountOut, tokenOutLimit, HSPOST_SWAP_D); + assertLt(amountInMax, tokenInLimit, HSPOST_SWAP_D); } else { revert("EulerSwapPeripheryHandler: swapExactOut failed"); } @@ -89,23 +95,70 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { delete receiver; } - function quoteExactInput(uint256 amountIn, bool dir) external eulerSwapDeployed { + function quoteExactInput(uint256 amountIn, bool dir) external setup eulerSwapDeployed { + bool success; + (address tokenIn, address tokenOut) = _getAssetsByDir(dir); - try periphery.quoteExactInput(address(eulerSwap), tokenIn, tokenOut, amountIn) returns (uint256 tokenIn_) {} - catch Error(string memory) { + uint256 amountOutMin; + + try periphery.quoteExactInput(address(eulerSwap), tokenIn, tokenOut, amountIn) returns (uint256 amountOutMin_) { + amountOutMin = amountOutMin_; + + if (amountIn > IERC20(tokenIn).balanceOf(address(actor))) { + _mint(tokenIn, address(actor), amountIn); + } + } catch Error(string memory) { // HSPOST assertTrue(false, NR_QUOTE_A); } + + address target = address(periphery); + + _before(); + (success,) = actor.proxy( + target, + abi.encodeWithSelector( + IEulerSwapPeriphery.swapExactIn.selector, address(eulerSwap), tokenIn, tokenOut, amountIn, amountOutMin + ) + ); + _after(); + + // HSPOST + assertTrue(success, HSPOST_SWAP_E); } - function quoteExactOutput(uint256 amountOut, bool dir) external eulerSwapDeployed { + function quoteExactOutput(uint256 amountOut, bool dir) external setup eulerSwapDeployed { + bool success; + (address tokenIn, address tokenOut) = _getAssetsByDir(dir); - try periphery.quoteExactOutput(address(eulerSwap), tokenIn, tokenOut, amountOut) returns (uint256 tokenOut_) {} - catch Error(string memory) { + uint256 amountInMax; + + try periphery.quoteExactOutput(address(eulerSwap), tokenIn, tokenOut, amountOut) returns (uint256 amountInMax_) + { + amountInMax = amountInMax_; + + if (amountInMax > IERC20(tokenIn).balanceOf(address(actor))) { + _mint(tokenIn, address(actor), amountInMax); + } + } catch Error(string memory) { // HSPOST assertTrue(false, NR_QUOTE_B); } + + address target = address(periphery); + + _before(); + (success,) = actor.proxy( + target, + abi.encodeWithSelector( + IEulerSwapPeriphery.swapExactOut.selector, address(eulerSwap), tokenIn, tokenOut, amountOut, amountInMax + ) + ); + _after(); + + // HSPOST + assertTrue(success, HSPOST_SWAP_E); } } diff --git a/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol b/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol index d7b9c3c..9e3286b 100644 --- a/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol +++ b/test/enigma-dark-invariants/specs/InvariantsSpec.t.sol @@ -47,7 +47,7 @@ abstract contract InvariantsSpec { // TODO: Implement invariants for LTV checks from ChainSecurity report -> no implemented, checked with liquidation invariant // TODO: Implement invariants for liquidation checks from ChainSecurity report -> X // TODO: Implement invariants for reserve desynchronization from ChainSecurity report -> NO - // TODO: Implement invariant to ensure debt never exceeds the debt limit -> X + // TODO: Implement invariant to ensure debt never exceeds the debt limit -> X // TODO: Implement invariants from the team call notes -> TODO // TODO: Review the trust model of the protocol as outlined in the ChainSecurity report -> TODO // TODO: Review the binary search implementation -> TODO diff --git a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol index 14de72f..c9d5607 100644 --- a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol +++ b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol @@ -32,6 +32,10 @@ abstract contract PostconditionsSpec { string constant HSPOST_SWAP_C = "HSPOST_SWAP_C: User should receive the amount out specified after a swap"; + string constant HSPOST_SWAP_D = "HSPOST_SWAP_D: Successful swaps are always inside the swap limits"; + + string constant HSPOST_SWAP_E = "HSPOST_SWAP_E: Swaps with quoted amounts should always be successful"; + /////////////////////////////////////////////////////////////////////////////////////////////// // RESERVES // /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/utils/PropertiesAsserts.sol b/test/enigma-dark-invariants/utils/PropertiesAsserts.sol index b60a54e..487bb10 100644 --- a/test/enigma-dark-invariants/utils/PropertiesAsserts.sol +++ b/test/enigma-dark-invariants/utils/PropertiesAsserts.sol @@ -216,7 +216,8 @@ abstract contract PropertiesAsserts { } /// @notice Clamps value to be between low and high, exclusively (not including boundary points) - function clampBetweenExclusive(uint256 value, uint256 low, uint256 high) internal pure returns (uint256) {/// @dev + function clampBetweenExclusive(uint256 value, uint256 low, uint256 high) internal pure returns (uint256) { + /// @dev require(high > low + 1, "Invalid range: must have at least one value between low and high"); if (value <= low || value >= high) { return low + 1 + (value % (high - low - 1)); From 2e33e254f4b4c3cf16093df9667030776ca87d2e Mon Sep 17 00:00:00 2001 From: Elpacos Date: Mon, 31 Mar 2025 21:23:32 +0200 Subject: [PATCH 17/18] chore: refactor reserve postconditions and fix hook asset accounting --- .../CryticToFoundry.t.sol | 39 +++--- .../base/BaseHandler.t.sol | 115 +++++++++++------- .../swap/EulerSwapPeripheryHandler.t.sol | 8 +- .../hooks/DefaultBeforeAfterHooks.t.sol | 6 +- .../specs/PostconditionsSpec.t.sol | 18 ++- 5 files changed, 116 insertions(+), 70 deletions(-) diff --git a/test/enigma-dark-invariants/CryticToFoundry.t.sol b/test/enigma-dark-invariants/CryticToFoundry.t.sol index 9546c46..0fd195c 100644 --- a/test/enigma-dark-invariants/CryticToFoundry.t.sol +++ b/test/enigma-dark-invariants/CryticToFoundry.t.sol @@ -71,7 +71,7 @@ contract CryticToFoundry is Invariants, Setup { Tester.roundtripSwap(200000000, 0); } */ - function test_replay_setupEulerSwap() public { + /* function test_replay_setupEulerSwap() public { //@audit-ok fixed by clamping fee Tester.setupEulerSwap( 0, @@ -85,35 +85,40 @@ contract CryticToFoundry is Invariants, Setup { } function test_replay_swapExactOut() public { - //@audit Invalid: 1!=0, reason: HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed + //@audit-ok Invalid: 1!=0, reason: HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed Tester.setupEulerSwap(0, 0, 0, 0, IEulerSwap.CurveParams(0, 0, 0, 0)); Tester.swap(0, 0, 1, 0, 0); Tester.mint(1, 1, 0); Tester.redeem(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 0); + console.log("########################"); + console.log("debt2", eTST.debtOf(address(holder))); Tester.swapExactOut(0, 0, false); } - function test_replay_roundtripSwap() public { - //@audit Invalid: 1999999999999999999999<2000000000000000000000 failed, reason: HSPOST_SWAP_A: Holder's NAV should increase monotonically - Tester.setupEulerSwap(0, 0, 0, 0, IEulerSwap.CurveParams(2069895513206400, 0, 0, 77696590)); - Tester.roundtripSwap(1, 0); - } - - function test_replay_swap() public { - //@audit Invalid: 1!=0, reason: HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed - Tester.setupEulerSwap(0, 0, 0, 0, IEulerSwap.CurveParams(0, 0, 0, 0)); - Tester.redeem(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 1); - Tester.mint(1, 1, 1); - Tester.swap(0, 1, 2, 0, 0); - } - function test_replay_swapExactIn() public { - //@audit Invalid: 1!=0, reason: HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed + //@audit-ok Invalid: 1!=0, reason: HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed Tester.setupEulerSwap(0, 0, 0, 0, IEulerSwap.CurveParams(0, 0, 0, 0)); Tester.mint(1, 1, 0); Tester.redeem(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 0); Tester.donateUnderlying(2, 1); Tester.swapExactIn(0, 0, true); + } */ + + /* function test_replay_swap() public { + //@audit-ok Invalid: 1!=0, reason: HSPOST_RESERVES_A: If there is debt in tokenIn, the debt must be repaid + Tester.setupEulerSwap(0, 0, 0, 0, IEulerSwap.CurveParams(0, 0, 0, 0)); + Tester.redeem(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 1); + Tester.mint(1, 1, 1); + console.log("########################"); + console.log("debt2", eTST2.debtOf(address(holder))); + console.log("balance2", eTST2.balanceOf(address(holder))); + Tester.swap(0, 1, 2, 0, 0); + } */ + + function test_replay_roundtripSwap() public { + //@audit Invalid: 1999999999999999999999<2000000000000000000000 failed, reason: HSPOST_SWAP_A: Holder's NAV should increase monotonically + Tester.setupEulerSwap(0, 0, 0, 0, IEulerSwap.CurveParams(2069895513206400, 0, 0, 77696590)); + Tester.roundtripSwap(1, 0); } /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/enigma-dark-invariants/base/BaseHandler.t.sol b/test/enigma-dark-invariants/base/BaseHandler.t.sol index 8e55766..eb26cff 100644 --- a/test/enigma-dark-invariants/base/BaseHandler.t.sol +++ b/test/enigma-dark-invariants/base/BaseHandler.t.sol @@ -12,6 +12,8 @@ import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {Actor} from "../utils/Actor.sol"; import {HookAggregator} from "../hooks/HookAggregator.t.sol"; +import "forge-std/console.sol"; + /// @title BaseHandler /// @notice Contains common logic for all handlers /// @dev inherits all suite assertions since per action assertions are implmenteds in the handlers @@ -119,7 +121,7 @@ contract BaseHandler is HookAggregator { function _eulerSwapPostconditions(uint256 amount0Out, uint256 amount1Out, uint256 amount0In, uint256 amount1In) internal { - /// @dev HSPOST_SWAP_C + // SWAP POSTCONDITIONS if (amount0Out > 0) { assertEq( @@ -137,52 +139,83 @@ contract BaseHandler is HookAggregator { ); } - /// @dev HSPOST_SWAP_A - assertGe(defaultVarsAfter.holderNAV, defaultVarsBefore.holderNAV, HSPOST_SWAP_A); - /// @dev HSPOST_RESERVES_A - - if (amount0In < defaultVarsBefore.holderETSTDebt) { - assertEq(defaultVarsAfter.holderETSTDebt, defaultVarsBefore.holderETSTDebt - amount0In, HSPOST_SWAP_B); - } else { - assertEq(defaultVarsAfter.holderETSTDebt, 0, HSPOST_RESERVES_A); - } - - if (amount1In < defaultVarsBefore.holderETST2Debt) { - assertEq(defaultVarsAfter.holderETST2Debt, defaultVarsBefore.holderETST2Debt - amount1In, HSPOST_SWAP_B); - } else { - assertEq(defaultVarsAfter.holderETST2Debt, 0, HSPOST_RESERVES_A); - } - - /// @dev HSPOST_RESERVES_B + // RESERVES POSTCONDITIONS + + int256 amount0Delta = int256(amount0In) - int256(amount0Out); + int256 amount1Delta = int256(amount1In) - int256(amount1Out); + + /// asset0 (eTST) + _checkAssetChanges( + amount0Delta, + defaultVarsBefore.holderETSTDebt, + defaultVarsAfter.holderETSTDebt, + defaultVarsBefore.holderETSTAssets, + defaultVarsAfter.holderETSTAssets, + "token0" + ); + + /// asset1 (eTST2) + _checkAssetChanges( + amount1Delta, + defaultVarsBefore.holderETST2Debt, + defaultVarsAfter.holderETST2Debt, + defaultVarsBefore.holderETST2Assets, + defaultVarsAfter.holderETST2Assets, + "token1" + ); + + // DEBT POSTCONDITIONS - if (amount0Out < defaultVarsBefore.holderETSTAssets) { - assertEq( - defaultVarsAfter.holderETSTAssets, defaultVarsBefore.holderETSTAssets - amount0Out, HSPOST_RESERVES_B - ); - } else { - assertEq(defaultVarsAfter.holderETSTAssets, 0, HSPOST_RESERVES_B); - assertEq( - defaultVarsAfter.holderETSTDebt, amount0Out - defaultVarsBefore.holderETSTAssets, HSPOST_RESERVES_C - ); - } - - if (amount1Out < defaultVarsBefore.holderETST2Assets) { - assertEq( - defaultVarsAfter.holderETST2Assets, defaultVarsBefore.holderETST2Assets - amount1Out, HSPOST_RESERVES_B - ); - } else { - assertEq(defaultVarsAfter.holderETST2Assets, 0, HSPOST_RESERVES_B); - assertEq( - defaultVarsAfter.holderETST2Debt, amount1Out - defaultVarsBefore.holderETST2Assets, HSPOST_RESERVES_C - ); - } - - /// @dev HSPOST_DEBT_A assertLe(defaultVarsAfter.holderETSTDebt, eulerSwap.reserve0(), HSPOST_DEBT_A); assertLe(defaultVarsAfter.holderETST2Debt, eulerSwap.reserve1(), HSPOST_DEBT_A); assertLe(defaultVarsAfter.holderETSTDebt, eulerSwap.reserve1(), HSPOST_DEBT_A); assertLe(defaultVarsAfter.holderETST2Debt, eulerSwap.reserve0(), HSPOST_DEBT_A); } + + function _checkAssetChanges( + int256 amountDelta, + uint256 beforeDebt, + uint256 afterDebt, + uint256 beforeAssets, + uint256 afterAssets, + string memory tokenId + ) internal { + if (amountDelta > 0) { + // Positive delta means repaying debt first, then possibly increasing assets + if (uint256(amountDelta) < beforeDebt) { + // Just reduce debt + assertEq( + afterDebt, beforeDebt - uint256(amountDelta), string.concat(HSPOST_RESERVES_A, " for ", tokenId) + ); + } else { + // Debt is fully repaid + assertEq(afterDebt, 0, string.concat(HSPOST_RESERVES_B, " for ", tokenId)); + + // If there's excess after repaying debt, it should increase assets + uint256 excess = uint256(amountDelta) - beforeDebt; + if (excess > 0) { + assertEq(afterAssets, beforeAssets + excess, string.concat(HSPOST_RESERVES_C, " for ", tokenId)); + } + } + } else { + // Negative delta means using assets first, then borrowing + if (uint256(-amountDelta) < beforeAssets) { + // Just reduce assets + assertEq( + afterAssets, + beforeAssets - uint256(-amountDelta), + string.concat(HSPOST_RESERVES_D, " for ", tokenId) + ); + } else { + // Assets are depleted + assertEq(afterAssets, 0, string.concat(HSPOST_RESERVES_E, " for ", tokenId)); + + // Any deficit beyond available assets increases debt + uint256 deficit = uint256(-amountDelta) - beforeAssets; + assertEq(afterDebt - beforeDebt, deficit, string.concat(HSPOST_RESERVES_F, " for ", tokenId)); + } + } + } } diff --git a/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol b/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol index 3654442..e51f145 100644 --- a/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol +++ b/test/enigma-dark-invariants/handlers/swap/EulerSwapPeripheryHandler.t.sol @@ -50,8 +50,8 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { } // HSPOST - assertGt(amountIn, tokenInLimit, HSPOST_SWAP_D); - assertLt(amountOutMin, tokenOutLimit, HSPOST_SWAP_D); + assertLe(amountIn, tokenInLimit, HSPOST_SWAP_D); + assertLe(amountOutMin, tokenOutLimit, HSPOST_SWAP_D); } else { revert("EulerSwapPeripheryHandler: swapExactIn failed"); } @@ -86,8 +86,8 @@ abstract contract EulerSwapPeripheryHandler is BaseHandler { } // HSPOST - assertGt(amountOut, tokenOutLimit, HSPOST_SWAP_D); - assertLt(amountInMax, tokenInLimit, HSPOST_SWAP_D); + assertLe(amountOut, tokenOutLimit, HSPOST_SWAP_D); + assertLe(amountInMax, tokenInLimit, HSPOST_SWAP_D); } else { revert("EulerSwapPeripheryHandler: swapExactOut failed"); } diff --git a/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol b/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol index 6e67125..0eac5cd 100644 --- a/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol +++ b/test/enigma-dark-invariants/hooks/DefaultBeforeAfterHooks.t.sol @@ -76,11 +76,9 @@ abstract contract DefaultBeforeAfterHooks is BaseHooks { function _setDefaultValues(DefaultVars storage _defaultVars) internal { // Holder _defaultVars.holderNAV = _getHolderNAV(); - _defaultVars.holderETSTAssets = - eTST.convertToAssets(eTST.balanceOf(holder)) + assetTST.balanceOf(address(eulerSwap)); + _defaultVars.holderETSTAssets = eTST.convertToAssets(eTST.balanceOf(holder)); /// @dev adding eulerSwap balance to take donations into account - _defaultVars.holderETST2Assets = - eTST2.convertToAssets(eTST2.balanceOf(holder)) + assetTST2.balanceOf(address(eulerSwap)); + _defaultVars.holderETST2Assets = eTST2.convertToAssets(eTST2.balanceOf(holder)); _defaultVars.holderETSTDebt = eTST.debtOf(holder); _defaultVars.holderETST2Debt = eTST2.debtOf(holder); } diff --git a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol index c9d5607..68e70e5 100644 --- a/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol +++ b/test/enigma-dark-invariants/specs/PostconditionsSpec.t.sol @@ -40,17 +40,27 @@ abstract contract PostconditionsSpec { // RESERVES // /////////////////////////////////////////////////////////////////////////////////////////////// - string constant HSPOST_RESERVES_A = "HSPOST_RESERVES_A: If there is debt in tokenIn, the debt must be repaid"; + string constant HSPOST_RESERVES_A = + "HSPOST_RESERVES_A: When positive delta exists, debt must decrease by min(delta, previous_debt)"; string constant HSPOST_RESERVES_B = - "HSPOST_RESERVES_B: If amountOut does not exceed tokenOut collateral, tokenOut amount is withdrawn"; + "HSPOST_RESERVES_B: When positive delta is greater than previous debt, debt is fully repaid"; string constant HSPOST_RESERVES_C = - "HSPOST_RESERVES_C: If amountIn tokenOut collateral, a specific amountOut is borrowed"; + "HSPOST_RESERVES_C: When positive delta is greater than previous debt, the excess delta is added to assets"; + + string constant HSPOST_RESERVES_D = + "HSPOST_RESERVES_D: When negative delta exists, assets must decrease by min(delta, previous_assets)"; + + string constant HSPOST_RESERVES_E = + "HSPOST_RESERVES_E: When negative delta is greater than previous assets, assets are fully depleted"; + + string constant HSPOST_RESERVES_F = + "HSPOST_RESERVES_F: When negative delta is greater than previous assets, the deficit is added to debt"; /////////////////////////////////////////////////////////////////////////////////////////////// // DEBT // /////////////////////////////////////////////////////////////////////////////////////////////// - string constant HSPOST_DEBT_A = "HSPOST_DEBT_A: Debt on an asset should never exceed the debt limit"; + string constant HSPOST_DEBT_A = "HSPOST_DEBT_A: Debt on an asset after a swap should never exceed the debt limit"; } From d6adbe0f6daeaa79745ca67e7954652e646dd754 Mon Sep 17 00:00:00 2001 From: Elpacos Date: Mon, 31 Mar 2025 22:03:05 +0200 Subject: [PATCH 18/18] fix: formatting --- test/enigma-dark-invariants/base/BaseHandler.t.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/enigma-dark-invariants/base/BaseHandler.t.sol b/test/enigma-dark-invariants/base/BaseHandler.t.sol index eb26cff..66d52ff 100644 --- a/test/enigma-dark-invariants/base/BaseHandler.t.sol +++ b/test/enigma-dark-invariants/base/BaseHandler.t.sol @@ -123,6 +123,8 @@ contract BaseHandler is HookAggregator { { // SWAP POSTCONDITIONS + assertGe(defaultVarsAfter.holderNAV, defaultVarsBefore.holderNAV, HSPOST_SWAP_A); + if (amount0Out > 0) { assertEq( defaultVarsAfter.users[receiver].assetTSTBalance, @@ -139,8 +141,6 @@ contract BaseHandler is HookAggregator { ); } - assertGe(defaultVarsAfter.holderNAV, defaultVarsBefore.holderNAV, HSPOST_SWAP_A); - // RESERVES POSTCONDITIONS int256 amount0Delta = int256(amount0In) - int256(amount0Out);