From 4a88f0160e3d742843dcfd226e63f6cb78b6dffb Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 2 Dec 2024 14:01:30 -0500 Subject: [PATCH 001/312] forge install: forge-std v1.9.4 --- .gitmodules | 3 +++ lib/forge-std | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 lib/forge-std diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..888d42d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/lib/forge-std b/lib/forge-std new file mode 160000 index 0000000..1eea5ba --- /dev/null +++ b/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 1eea5bae12ae557d589f9f0f0edae2faa47cb262 From db5abda1be78f5fd097533cf839ca469daf8cab9 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 2 Dec 2024 14:04:12 -0500 Subject: [PATCH 002/312] initial check-in --- .gitignore | 3 - README.md | 67 +--------- docs/maglev.png | Bin 0 -> 270813 bytes script/Counter.s.sol | 19 --- src/AMMLevConstantSum.sol | 44 +++++++ src/BaseAMMLev.sol | 141 +++++++++++++++++++++ src/Counter.sol | 14 --- src/interfaces/IUniswapV2Callee.sol | 6 + test/AMMLev.t.sol | 189 ++++++++++++++++++++++++++++ test/Counter.t.sol | 24 ---- 10 files changed, 382 insertions(+), 125 deletions(-) create mode 100644 docs/maglev.png delete mode 100644 script/Counter.s.sol create mode 100644 src/AMMLevConstantSum.sol create mode 100644 src/BaseAMMLev.sol delete mode 100644 src/Counter.sol create mode 100644 src/interfaces/IUniswapV2Callee.sol create mode 100644 test/AMMLev.t.sol delete mode 100644 test/Counter.t.sol diff --git a/.gitignore b/.gitignore index 85198aa..3269660 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,5 @@ out/ /broadcast/*/31337/ /broadcast/**/dry-run/ -# Docs -docs/ - # Dotenv file .env diff --git a/README.md b/README.md index 9265b45..3acff48 100644 --- a/README.md +++ b/README.md @@ -1,66 +1,3 @@ -## Foundry +## Euler Maglev -**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** - -Foundry consists of: - -- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). -- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. -- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. -- **Chisel**: Fast, utilitarian, and verbose solidity REPL. - -## Documentation - -https://book.getfoundry.sh/ - -## Usage - -### Build - -```shell -$ forge build -``` - -### Test - -```shell -$ forge test -``` - -### Format - -```shell -$ forge fmt -``` - -### Gas Snapshots - -```shell -$ forge snapshot -``` - -### Anvil - -```shell -$ anvil -``` - -### Deploy - -```shell -$ forge script script/Counter.s.sol:CounterScript --rpc-url --private-key -``` - -### Cast - -```shell -$ cast -``` - -### Help - -```shell -$ forge --help -$ anvil --help -$ cast --help -``` +![maglev logo](docs/maglev.png) diff --git a/docs/maglev.png b/docs/maglev.png new file mode 100644 index 0000000000000000000000000000000000000000..700067ad375a8934276fd2b575fcb6e5a6baf415 GIT binary patch literal 270813 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
a?68$TWLysm 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 literal 0 HcmV?d00001 diff --git a/script/Counter.s.sol b/script/Counter.s.sol deleted file mode 100644 index cdc1fe9..0000000 --- a/script/Counter.s.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import {Script, console} from "forge-std/Script.sol"; -import {Counter} from "../src/Counter.sol"; - -contract CounterScript is Script { - Counter public counter; - - function setUp() public {} - - function run() public { - vm.startBroadcast(); - - counter = new Counter(); - - vm.stopBroadcast(); - } -} diff --git a/src/AMMLevConstantSum.sol b/src/AMMLevConstantSum.sol new file mode 100644 index 0000000..a28cee7 --- /dev/null +++ b/src/AMMLevConstantSum.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +import {BaseAMMLev} from "./BaseAMMLev.sol"; + +/// @dev Simple constant-sum curve. FIXME: Assumes tokens are 1:1 pegged and have same decimals. +contract AMMLevConstantSum is BaseAMMLev { + uint256 fee; + + constructor(BaseAMMLev.Params memory params, uint256 _fee) BaseAMMLev(params) { + fee = _fee; + } + + function setFee(uint256 newFee) external onlyOwner { + fee = newFee; + } + + function k(uint256 r0, uint256 r1) internal pure returns (uint256) { + return r0 + r1; + } + + function verify( + uint256 oldReserve0, + uint256 oldReserve1, + uint256 amount0In, + uint256 amount1In, + uint256 newReserve0, + uint256 newReserve1 + ) internal view virtual override { + uint256 kBefore = k(oldReserve0, oldReserve1); + uint256 kAfter = k(newReserve0 - (amount0In * fee / 1e18), newReserve1 - (amount1In * fee / 1e18)); + require(kAfter >= kBefore, "k not satisfied"); + } + + // FIXME: quote functions should consider limits like reserve size and vault utilisation + + function quoteGivenIn(uint256 amount, bool) public view returns (uint256) { + return amount * (1e18 - fee) / 1e18; + } + + function quoteGivenOut(uint256 amount, bool) public view returns (uint256) { + return amount * 1e18 / (1e18 - fee); + } +} diff --git a/src/BaseAMMLev.sol b/src/BaseAMMLev.sol new file mode 100644 index 0000000..d1572ab --- /dev/null +++ b/src/BaseAMMLev.sol @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +import {Ownable, Context} from "openzeppelin-contracts/access/Ownable.sol"; +import {EVCUtil} from "evc/utils/EVCUtil.sol"; +import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; +import {IEVault, IERC20, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; +import {IUniswapV2Callee} from "./interfaces/IUniswapV2Callee.sol"; + +abstract contract BaseAMMLev is EVCUtil, Ownable { + address public immutable vault0; + address public immutable vault1; + address public immutable asset0; + address public immutable asset1; + address public immutable myAccount; + + uint112 public reserve0; + uint112 public reserve1; + uint32 private locked; + + modifier nonReentrant() { + require(locked == 0, "reentrancy"); + locked = 1; + _; + locked = 0; + } + + function _msgSender() internal view override (Context, EVCUtil) returns (address) { + return EVCUtil._msgSender(); + } + + struct Params { + address evc; + address vault0; + address vault1; + address myAccount; + } + + constructor(Params memory params) EVCUtil(params.evc) Ownable(msg.sender) { + vault0 = params.vault0; + vault1 = params.vault1; + asset0 = IEVault(vault0).asset(); + asset1 = IEVault(vault1).asset(); + myAccount = params.myAccount; + } + + /// @dev Call *after* installing as operator + function configure(uint112 _reserve0, uint112 _reserve1) external onlyOwner { + reserve0 = _reserve0; + reserve1 = _reserve1; + + IERC20(asset0).approve(vault0, type(uint256).max); + IERC20(asset1).approve(vault1, type(uint256).max); + + IEVC(evc).enableCollateral(myAccount, vault0); + IEVC(evc).enableCollateral(myAccount, vault1); + } + + function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) + external + callThroughEVC + nonReentrant + { + // Optimistically send tokens + + if (amount0Out > 0) withdrawAssets(vault0, amount0Out, to); + if (amount1Out > 0) withdrawAssets(vault1, amount1Out, to); + + // Invoke callback + + if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data); + + // Deposit all available funds + + uint256 amount0In = IERC20(asset0).balanceOf(address(this)); + uint256 amount1In = IERC20(asset1).balanceOf(address(this)); + if (amount0In > 0) depositAssets(vault0, amount0In); + if (amount1In > 0) depositAssets(vault1, amount1In); + + // Verify curve invariant is satisified + + { + uint256 oldReserve0 = reserve0; + uint256 oldReserve1 = reserve1; + uint256 newReserve0 = oldReserve0 + amount0In - amount0Out; + uint256 newReserve1 = oldReserve1 + amount1In - amount1Out; + + require(newReserve0 <= type(uint112).max && newReserve1 <= type(uint112).max, "overflow"); + verify(oldReserve0, oldReserve1, amount0In, amount1In, newReserve0, newReserve1); + + reserve0 = uint112(newReserve0); + reserve1 = uint112(newReserve1); + } + } + + function withdrawAssets(address vault, uint256 amount, address to) internal { + uint256 balance; + { + uint256 shares = IEVault(vault).balanceOf(myAccount); + balance = shares == 0 ? 0 : IEVault(vault).convertToAssets(shares); + } + + if (balance > 0) { + uint256 a = amount < balance ? amount : balance; + IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IERC4626.withdraw, (a, to, myAccount))); + amount -= a; + } + + if (amount > 0) { + IEVC(evc).enableController(myAccount, vault); + IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IBorrowing.borrow, (amount, to))); + } + } + + function depositAssets(address vault, uint256 amount) internal { + IEVault(vault).deposit(amount, myAccount); + + uint256 debt = IEVault(vault).debtOf(myAccount); + + if (debt > 0) { + IEVC(evc).call( + vault, myAccount, 0, abi.encodeCall(IBorrowing.repayWithShares, (type(uint256).max, myAccount)) + ); + + if (debt <= amount) { + IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IRiskManager.disableController, ())); + } + } + } + + // Verification implemented by sub-class + + function verify( + uint256 oldReserve0, + uint256 oldReserve1, + uint256 amount0In, + uint256 amount1In, + uint256 newReserve0, + uint256 newReserve1 + ) internal view virtual; +} diff --git a/src/Counter.sol b/src/Counter.sol deleted file mode 100644 index aded799..0000000 --- a/src/Counter.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -contract Counter { - uint256 public number; - - function setNumber(uint256 newNumber) public { - number = newNumber; - } - - function increment() public { - number++; - } -} diff --git a/src/interfaces/IUniswapV2Callee.sol b/src/interfaces/IUniswapV2Callee.sol new file mode 100644 index 0000000..4c99ebb --- /dev/null +++ b/src/interfaces/IUniswapV2Callee.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +interface IUniswapV2Callee { + function uniswapV2Call(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external; +} diff --git a/test/AMMLev.t.sol b/test/AMMLev.t.sol new file mode 100644 index 0000000..ee586ee --- /dev/null +++ b/test/AMMLev.t.sol @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.24; + +import {Test, console} from "forge-std/Test.sol"; +import {EVaultTestBase, TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; +import {IEVault, IERC20, IBorrowing, IERC4626} from "evk/EVault/IEVault.sol"; +import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; + +import {BaseAMMLev} from "../../src/AMMLev/BaseAMMLev.sol"; +import {AMMLevConstantSum as AMMLev} from "../../src/AMMLev/AMMLevConstantSum.sol"; + +contract AMMLevTest is EVaultTestBase { + AMMLev public ammlev; + + address public depositor = makeAddr("depositor"); + address public owner = makeAddr("owner"); + address public holder = makeAddr("holder"); + address public recipient = makeAddr("recipient"); + + function setUp() public override { + super.setUp(); + + // Vault config + + eTST.setLTV(address(eTST2), 0.9e4, 0.9e4, 0); + eTST2.setLTV(address(eTST), 0.9e4, 0.9e4, 0); + + // Pricing + + oracle.setPrice(address(assetTST), unitOfAccount, 1e18); + oracle.setPrice(address(assetTST2), unitOfAccount, 1e18); + oracle.setPrice(address(eTST), unitOfAccount, 1e18); + oracle.setPrice(address(eTST2), unitOfAccount, 1e18); + + oracle.setPrice(address(assetTST), address(assetTST2), 1e18); + oracle.setPrice(address(assetTST2), address(assetTST), 1e18); + + // Funding + + _mintAndDeposit(depositor, eTST, 100e18); + _mintAndDeposit(depositor, eTST2, 100e18); + + _mintAndDeposit(holder, eTST, 10e18); + _mintAndDeposit(holder, eTST2, 10e18); + + // Setup AMMLev + + vm.prank(owner); + ammlev = new AMMLev( + BaseAMMLev.Params({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder}), 0 + ); + + vm.prank(holder); + evc.setAccountOperator(holder, address(ammlev), true); + + vm.prank(owner); + ammlev.configure(100e18, 100e18); + } + + function _mintAndDeposit(address who, IEVault vault, uint256 amount) internal { + TestERC20 tok = TestERC20(vault.asset()); + tok.mint(who, amount); + + vm.prank(who); + tok.approve(address(vault), type(uint256).max); + + vm.prank(who); + vault.deposit(amount, who); + } + + function test_basicSwapReport() public { + uint256 amount = 25e18; + assetTST.mint(address(this), amount); + + logState(); + + assetTST.transfer(address(ammlev), amount); + ammlev.swap(0, amount, address(this), ""); + assertEq(assetTST2.balanceOf(address(this)), amount); + + logState(); + + uint256 amount2 = 50e18; + assetTST2.mint(address(this), amount2); + assetTST2.transfer(address(ammlev), amount2); + ammlev.swap(amount2, 0, address(this), ""); + + assetTST2.transfer(address(ammlev), 1e18); + ammlev.swap(1e18, 0, address(this), ""); + + logState(); + } + + function test_basicSwapFuzz(uint256 amount1, uint256 amount2) public { + amount1 = bound(amount1, 1e18, 25e18); + amount2 = bound(amount2, 1e18, 50e18); + + assetTST.mint(address(this), amount1); + assetTST.transfer(address(ammlev), amount1); + ammlev.swap(0, amount1, address(this), ""); + assertEq(assetTST.balanceOf(address(this)), 0); + assertEq(assetTST2.balanceOf(address(this)), amount1); + + assetTST2.mint(address(this), amount2); + assetTST2.transfer(address(ammlev), amount2); + ammlev.swap(amount2, 0, address(this), ""); + assertEq(assetTST.balanceOf(address(this)), amount2); + assertEq(assetTST2.balanceOf(address(this)), amount1); + } + + function logState() internal view { + console.log("--------------------"); + console.log("Account States:"); + console.log("HOLDER"); + console.log(" eTST Vault assets: ", eTST.convertToAssets(eTST.balanceOf(holder))); + console.log(" eTST Vault debt: ", eTST.debtOf(holder)); + console.log(" eTST2 Vault assets: ", eTST2.convertToAssets(eTST2.balanceOf(holder))); + console.log(" eTST2 Vault debt: ", eTST2.debtOf(holder)); + } + + function test_quoteGivenIn() public { + vm.prank(owner); + ammlev.setFee(0.003e18); + + assetTST.mint(address(this), 100e18); + uint256 q = ammlev.quoteGivenIn(1e18, true); + assertLt(q, 1e18); + assetTST.transfer(address(ammlev), 1e18); + + ammlev.swap(0, q, recipient, ""); + assertEq(assetTST2.balanceOf(recipient), q); + } + + function test_quoteGivenOut() public { + vm.prank(owner); + ammlev.setFee(0.003e18); + + assetTST.mint(address(this), 100e18); + + uint256 q = ammlev.quoteGivenOut(1e18, true); + assertGt(q, 1e18); + assetTST.transfer(address(ammlev), q); + + ammlev.swap(0, 1e18, recipient, ""); + assertEq(assetTST2.balanceOf(recipient), 1e18); + } + + function test_fees(uint256 fee, uint256 amount1, bool token0) public { + fee = bound(fee, 0, 0.02e18); + amount1 = bound(amount1, 1e18, 25e18); + + vm.prank(owner); + ammlev.setFee(fee); + + assetTST.mint(address(this), 100e18); + assetTST2.mint(address(this), 100e18); + + uint256 needed = amount1 * 1e18 / (1e18 - fee); + console.log(amount1, needed, fee); + + TestERC20 tt; + TestERC20 tt2; + uint256 a1; + uint256 a2; + + if (token0) { + tt = assetTST; + tt2 = assetTST2; + a1 = 0; + a2 = amount1; + } else { + tt = assetTST2; + tt2 = assetTST; + a1 = amount1; + a2 = 0; + } + + tt.transfer(address(ammlev), needed - 2); + + vm.expectRevert(bytes("k not satisfied")); + ammlev.swap(a1, a2, recipient, ""); + + tt.transfer(address(ammlev), 2); + ammlev.swap(a1, a2, recipient, ""); + + assertEq(tt2.balanceOf(recipient), amount1); + } +} diff --git a/test/Counter.t.sol b/test/Counter.t.sol deleted file mode 100644 index 54b724f..0000000 --- a/test/Counter.t.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import {Test, console} from "forge-std/Test.sol"; -import {Counter} from "../src/Counter.sol"; - -contract CounterTest is Test { - Counter public counter; - - function setUp() public { - counter = new Counter(); - counter.setNumber(0); - } - - function test_Increment() public { - counter.increment(); - assertEq(counter.number(), 1); - } - - function testFuzz_SetNumber(uint256 x) public { - counter.setNumber(x); - assertEq(counter.number(), x); - } -} From 4bd6f1d510dd8dccd32b8c2f82dbfd87fa35c893 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 2 Dec 2024 14:24:01 -0500 Subject: [PATCH 003/312] update --- .gitmodules | 9 +++ README.md | 10 +++ lib/ethereum-vault-connector | 1 + lib/euler-vault-kit | 1 + lib/openzeppelin-contracts | 1 + remappings.txt | 5 ++ src/{BaseAMMLev.sol => MaglevBase.sol} | 2 +- ...vConstantSum.sol => MaglevConstantSum.sol} | 6 +- test/{AMMLev.t.sol => ConstantSum.t.sol} | 64 +++++++++---------- 9 files changed, 63 insertions(+), 36 deletions(-) create mode 160000 lib/ethereum-vault-connector create mode 160000 lib/euler-vault-kit create mode 160000 lib/openzeppelin-contracts create mode 100644 remappings.txt rename src/{BaseAMMLev.sol => MaglevBase.sol} (98%) rename src/{AMMLevConstantSum.sol => MaglevConstantSum.sol} (87%) rename test/{AMMLev.t.sol => ConstantSum.t.sol} (74%) diff --git a/.gitmodules b/.gitmodules index 888d42d..7e69f48 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,12 @@ [submodule "lib/forge-std"] path = lib/forge-std url = https://github.com/foundry-rs/forge-std +[submodule "lib/openzeppelin-contracts"] + path = lib/openzeppelin-contracts + url = https://github.com/OpenZeppelin/openzeppelin-contracts +[submodule "lib/euler-vault-kit"] + path = lib/euler-vault-kit + url = https://github.com/euler-xyz/euler-vault-kit +[submodule "lib/ethereum-vault-connector"] + path = lib/ethereum-vault-connector + url = https://github.com/euler-xyz/ethereum-vault-connector diff --git a/README.md b/README.md index 3acff48..74f6d14 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,13 @@ ## Euler Maglev ![maglev logo](docs/maglev.png) + +Maglev is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) as leveraged lending products in order to extend the range of its reserves and thereby improve the capital efficiency of liquidity provisioning. + +It implements a conventional Uniswap2-style interface, but internally supports custom pricing curves and other advanced functionality. + +## License + +(c) 2024 Euler Labs Ltd. + +All rights reserved. diff --git a/lib/ethereum-vault-connector b/lib/ethereum-vault-connector new file mode 160000 index 0000000..4538f07 --- /dev/null +++ b/lib/ethereum-vault-connector @@ -0,0 +1 @@ +Subproject commit 4538f07342d116c6ade2af6d2aeac5398bfb578d diff --git a/lib/euler-vault-kit b/lib/euler-vault-kit new file mode 160000 index 0000000..83481a4 --- /dev/null +++ b/lib/euler-vault-kit @@ -0,0 +1 @@ +Subproject commit 83481a4e95d4d2ee50c95843841be952bbf3f48d diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts new file mode 160000 index 0000000..a3a6db8 --- /dev/null +++ b/lib/openzeppelin-contracts @@ -0,0 +1 @@ +Subproject commit a3a6db86d5b4d7ef003b6f71e6504867d2679a7f diff --git a/remappings.txt b/remappings.txt new file mode 100644 index 0000000..5e34eeb --- /dev/null +++ b/remappings.txt @@ -0,0 +1,5 @@ +openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/ +evc/=lib/ethereum-vault-connector/src/ +evk/=lib/euler-vault-kit/src/ +ethereum-vault-connector/=lib/ethereum-vault-connector/src/ +evk-test/=lib/euler-vault-kit/test/ diff --git a/src/BaseAMMLev.sol b/src/MaglevBase.sol similarity index 98% rename from src/BaseAMMLev.sol rename to src/MaglevBase.sol index d1572ab..bcf58d9 100644 --- a/src/BaseAMMLev.sol +++ b/src/MaglevBase.sol @@ -7,7 +7,7 @@ import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault, IERC20, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; import {IUniswapV2Callee} from "./interfaces/IUniswapV2Callee.sol"; -abstract contract BaseAMMLev is EVCUtil, Ownable { +abstract contract MaglevBase is EVCUtil, Ownable { address public immutable vault0; address public immutable vault1; address public immutable asset0; diff --git a/src/AMMLevConstantSum.sol b/src/MaglevConstantSum.sol similarity index 87% rename from src/AMMLevConstantSum.sol rename to src/MaglevConstantSum.sol index a28cee7..b35eee7 100644 --- a/src/AMMLevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.0; -import {BaseAMMLev} from "./BaseAMMLev.sol"; +import {MaglevBase} from "./MaglevBase.sol"; /// @dev Simple constant-sum curve. FIXME: Assumes tokens are 1:1 pegged and have same decimals. -contract AMMLevConstantSum is BaseAMMLev { +contract MaglevConstantSum is MaglevBase { uint256 fee; - constructor(BaseAMMLev.Params memory params, uint256 _fee) BaseAMMLev(params) { + constructor(MaglevBase.Params memory params, uint256 _fee) MaglevBase(params) { fee = _fee; } diff --git a/test/AMMLev.t.sol b/test/ConstantSum.t.sol similarity index 74% rename from test/AMMLev.t.sol rename to test/ConstantSum.t.sol index ee586ee..26bb551 100644 --- a/test/AMMLev.t.sol +++ b/test/ConstantSum.t.sol @@ -7,11 +7,11 @@ import {EVaultTestBase, TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.s import {IEVault, IERC20, IBorrowing, IERC4626} from "evk/EVault/IEVault.sol"; import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; -import {BaseAMMLev} from "../../src/AMMLev/BaseAMMLev.sol"; -import {AMMLevConstantSum as AMMLev} from "../../src/AMMLev/AMMLevConstantSum.sol"; +import {MaglevBase} from "../src/MaglevBase.sol"; +import {MaglevConstantSum} from "../src/MaglevConstantSum.sol"; -contract AMMLevTest is EVaultTestBase { - AMMLev public ammlev; +contract ConstantSumTest is EVaultTestBase { + MaglevConstantSum public maglev; address public depositor = makeAddr("depositor"); address public owner = makeAddr("owner"); @@ -44,18 +44,18 @@ contract AMMLevTest is EVaultTestBase { _mintAndDeposit(holder, eTST, 10e18); _mintAndDeposit(holder, eTST2, 10e18); - // Setup AMMLev + // Setup Maglev vm.prank(owner); - ammlev = new AMMLev( - BaseAMMLev.Params({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder}), 0 + maglev = new MaglevConstantSum( + MaglevBase.Params({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder}), 0 ); vm.prank(holder); - evc.setAccountOperator(holder, address(ammlev), true); + evc.setAccountOperator(holder, address(maglev), true); vm.prank(owner); - ammlev.configure(100e18, 100e18); + maglev.configure(100e18, 100e18); } function _mintAndDeposit(address who, IEVault vault, uint256 amount) internal { @@ -75,19 +75,19 @@ contract AMMLevTest is EVaultTestBase { logState(); - assetTST.transfer(address(ammlev), amount); - ammlev.swap(0, amount, address(this), ""); + assetTST.transfer(address(maglev), amount); + maglev.swap(0, amount, address(this), ""); assertEq(assetTST2.balanceOf(address(this)), amount); logState(); uint256 amount2 = 50e18; assetTST2.mint(address(this), amount2); - assetTST2.transfer(address(ammlev), amount2); - ammlev.swap(amount2, 0, address(this), ""); + assetTST2.transfer(address(maglev), amount2); + maglev.swap(amount2, 0, address(this), ""); - assetTST2.transfer(address(ammlev), 1e18); - ammlev.swap(1e18, 0, address(this), ""); + assetTST2.transfer(address(maglev), 1e18); + maglev.swap(1e18, 0, address(this), ""); logState(); } @@ -97,14 +97,14 @@ contract AMMLevTest is EVaultTestBase { amount2 = bound(amount2, 1e18, 50e18); assetTST.mint(address(this), amount1); - assetTST.transfer(address(ammlev), amount1); - ammlev.swap(0, amount1, address(this), ""); + assetTST.transfer(address(maglev), amount1); + maglev.swap(0, amount1, address(this), ""); assertEq(assetTST.balanceOf(address(this)), 0); assertEq(assetTST2.balanceOf(address(this)), amount1); assetTST2.mint(address(this), amount2); - assetTST2.transfer(address(ammlev), amount2); - ammlev.swap(amount2, 0, address(this), ""); + assetTST2.transfer(address(maglev), amount2); + maglev.swap(amount2, 0, address(this), ""); assertEq(assetTST.balanceOf(address(this)), amount2); assertEq(assetTST2.balanceOf(address(this)), amount1); } @@ -121,28 +121,28 @@ contract AMMLevTest is EVaultTestBase { function test_quoteGivenIn() public { vm.prank(owner); - ammlev.setFee(0.003e18); + maglev.setFee(0.003e18); assetTST.mint(address(this), 100e18); - uint256 q = ammlev.quoteGivenIn(1e18, true); + uint256 q = maglev.quoteGivenIn(1e18, true); assertLt(q, 1e18); - assetTST.transfer(address(ammlev), 1e18); + assetTST.transfer(address(maglev), 1e18); - ammlev.swap(0, q, recipient, ""); + maglev.swap(0, q, recipient, ""); assertEq(assetTST2.balanceOf(recipient), q); } function test_quoteGivenOut() public { vm.prank(owner); - ammlev.setFee(0.003e18); + maglev.setFee(0.003e18); assetTST.mint(address(this), 100e18); - uint256 q = ammlev.quoteGivenOut(1e18, true); + uint256 q = maglev.quoteGivenOut(1e18, true); assertGt(q, 1e18); - assetTST.transfer(address(ammlev), q); + assetTST.transfer(address(maglev), q); - ammlev.swap(0, 1e18, recipient, ""); + maglev.swap(0, 1e18, recipient, ""); assertEq(assetTST2.balanceOf(recipient), 1e18); } @@ -151,7 +151,7 @@ contract AMMLevTest is EVaultTestBase { amount1 = bound(amount1, 1e18, 25e18); vm.prank(owner); - ammlev.setFee(fee); + maglev.setFee(fee); assetTST.mint(address(this), 100e18); assetTST2.mint(address(this), 100e18); @@ -176,13 +176,13 @@ contract AMMLevTest is EVaultTestBase { a2 = 0; } - tt.transfer(address(ammlev), needed - 2); + tt.transfer(address(maglev), needed - 2); vm.expectRevert(bytes("k not satisfied")); - ammlev.swap(a1, a2, recipient, ""); + maglev.swap(a1, a2, recipient, ""); - tt.transfer(address(ammlev), 2); - ammlev.swap(a1, a2, recipient, ""); + tt.transfer(address(maglev), 2); + maglev.swap(a1, a2, recipient, ""); assertEq(tt2.balanceOf(recipient), amount1); } From d609aa758d504d6c19a8cdf8f956a740812dd3ea Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 2 Dec 2024 14:26:31 -0500 Subject: [PATCH 004/312] forge fmt --- src/MaglevBase.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index bcf58d9..6836fee 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -25,7 +25,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { locked = 0; } - function _msgSender() internal view override (Context, EVCUtil) returns (address) { + function _msgSender() internal view override(Context, EVCUtil) returns (address) { return EVCUtil._msgSender(); } From 1f445a05dd9e98c4515387173e80a526aaa9f6ad Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 2 Dec 2024 14:59:19 -0500 Subject: [PATCH 005/312] support pricing, alternate decimals --- src/MaglevBase.sol | 4 ++-- src/MaglevConstantSum.sol | 25 +++++++++++++++++-------- test/ConstantSum.t.sol | 9 +++++---- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 6836fee..698cf9e 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -29,14 +29,14 @@ abstract contract MaglevBase is EVCUtil, Ownable { return EVCUtil._msgSender(); } - struct Params { + struct BaseParams { address evc; address vault0; address vault1; address myAccount; } - constructor(Params memory params) EVCUtil(params.evc) Ownable(msg.sender) { + constructor(BaseParams memory params) EVCUtil(params.evc) Ownable(msg.sender) { vault0 = params.vault0; vault1 = params.vault1; asset0 = IEVault(vault0).asset(); diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index b35eee7..ff0f5c7 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -3,20 +3,29 @@ pragma solidity >=0.8.0; import {MaglevBase} from "./MaglevBase.sol"; -/// @dev Simple constant-sum curve. FIXME: Assumes tokens are 1:1 pegged and have same decimals. contract MaglevConstantSum is MaglevBase { - uint256 fee; + uint64 fee; + uint96 priceA; + uint96 priceB; + + struct ConstantSumParams { + uint64 fee; + uint96 priceA; + uint96 priceB; + } - constructor(MaglevBase.Params memory params, uint256 _fee) MaglevBase(params) { - fee = _fee; + constructor(BaseParams memory baseParams, ConstantSumParams memory params) MaglevBase(baseParams) { + setConstantSumParams(params); } - function setFee(uint256 newFee) external onlyOwner { - fee = newFee; + function setConstantSumParams(ConstantSumParams memory params) public onlyOwner { + fee = params.fee; + priceA = params.priceA; + priceB = params.priceB; } - function k(uint256 r0, uint256 r1) internal pure returns (uint256) { - return r0 + r1; + function k(uint256 r0, uint256 r1) internal view returns (uint256) { + return (r0 * priceA) + (r1 * priceB); } function verify( diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index 26bb551..bb5d9fd 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -48,7 +48,8 @@ contract ConstantSumTest is EVaultTestBase { vm.prank(owner); maglev = new MaglevConstantSum( - MaglevBase.Params({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder}), 0 + MaglevBase.BaseParams({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder}), + MaglevConstantSum.ConstantSumParams({fee: 0, priceA: 1, priceB: 1}) ); vm.prank(holder); @@ -121,7 +122,7 @@ contract ConstantSumTest is EVaultTestBase { function test_quoteGivenIn() public { vm.prank(owner); - maglev.setFee(0.003e18); + maglev.setConstantSumParams(MaglevConstantSum.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); assetTST.mint(address(this), 100e18); uint256 q = maglev.quoteGivenIn(1e18, true); @@ -134,7 +135,7 @@ contract ConstantSumTest is EVaultTestBase { function test_quoteGivenOut() public { vm.prank(owner); - maglev.setFee(0.003e18); + maglev.setConstantSumParams(MaglevConstantSum.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); assetTST.mint(address(this), 100e18); @@ -151,7 +152,7 @@ contract ConstantSumTest is EVaultTestBase { amount1 = bound(amount1, 1e18, 25e18); vm.prank(owner); - maglev.setFee(fee); + maglev.setConstantSumParams(MaglevConstantSum.ConstantSumParams({fee: uint64(fee), priceA: 1, priceB: 1})); assetTST.mint(address(this), 100e18); assetTST2.mint(address(this), 100e18); From 3bba4a209fee7e5f88bdae72528dc2586760d127 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 2 Dec 2024 15:07:20 -0500 Subject: [PATCH 006/312] cleanup --- src/MaglevBase.sol | 2 +- src/MaglevConstantSum.sol | 4 ++-- test/ConstantSum.t.sol | 19 +++++++++---------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 698cf9e..a509fc0 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.0; +pragma solidity ^0.8.0; import {Ownable, Context} from "openzeppelin-contracts/access/Ownable.sol"; import {EVCUtil} from "evc/utils/EVCUtil.sol"; diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index ff0f5c7..b50f0e9 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.0; +pragma solidity ^0.8.0; import {MaglevBase} from "./MaglevBase.sol"; @@ -24,7 +24,7 @@ contract MaglevConstantSum is MaglevBase { priceB = params.priceB; } - function k(uint256 r0, uint256 r1) internal view returns (uint256) { + function k(uint256 r0, uint256 r1) public view returns (uint256) { return (r0 * priceA) + (r1 * priceB); } diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index bb5d9fd..fe2d1f8 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -3,15 +3,14 @@ pragma solidity ^0.8.24; import {Test, console} from "forge-std/Test.sol"; + import {EVaultTestBase, TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; -import {IEVault, IERC20, IBorrowing, IERC4626} from "evk/EVault/IEVault.sol"; -import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; -import {MaglevBase} from "../src/MaglevBase.sol"; -import {MaglevConstantSum} from "../src/MaglevConstantSum.sol"; +import {MaglevBase, MaglevConstantSum as Maglev} from "../src/MaglevConstantSum.sol"; contract ConstantSumTest is EVaultTestBase { - MaglevConstantSum public maglev; + Maglev public maglev; address public depositor = makeAddr("depositor"); address public owner = makeAddr("owner"); @@ -47,9 +46,9 @@ contract ConstantSumTest is EVaultTestBase { // Setup Maglev vm.prank(owner); - maglev = new MaglevConstantSum( + maglev = new Maglev( MaglevBase.BaseParams({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder}), - MaglevConstantSum.ConstantSumParams({fee: 0, priceA: 1, priceB: 1}) + Maglev.ConstantSumParams({fee: 0, priceA: 1, priceB: 1}) ); vm.prank(holder); @@ -122,7 +121,7 @@ contract ConstantSumTest is EVaultTestBase { function test_quoteGivenIn() public { vm.prank(owner); - maglev.setConstantSumParams(MaglevConstantSum.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); + maglev.setConstantSumParams(Maglev.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); assetTST.mint(address(this), 100e18); uint256 q = maglev.quoteGivenIn(1e18, true); @@ -135,7 +134,7 @@ contract ConstantSumTest is EVaultTestBase { function test_quoteGivenOut() public { vm.prank(owner); - maglev.setConstantSumParams(MaglevConstantSum.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); + maglev.setConstantSumParams(Maglev.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); assetTST.mint(address(this), 100e18); @@ -152,7 +151,7 @@ contract ConstantSumTest is EVaultTestBase { amount1 = bound(amount1, 1e18, 25e18); vm.prank(owner); - maglev.setConstantSumParams(MaglevConstantSum.ConstantSumParams({fee: uint64(fee), priceA: 1, priceB: 1})); + maglev.setConstantSumParams(Maglev.ConstantSumParams({fee: uint64(fee), priceA: 1, priceB: 1})); assetTST.mint(address(this), 100e18); assetTST2.mint(address(this), 100e18); From dc58f8c25463dd8dcc68ba2924051434e2804a33 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 2 Dec 2024 15:35:03 -0500 Subject: [PATCH 007/312] todo --- TODO | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 0000000..806767b --- /dev/null +++ b/TODO @@ -0,0 +1,26 @@ +* quoting should consider reserves, utilisation +* structured errors +* better error messages when exceeding virtual reserves +* pause guardian +? re-sync reserves: if the vault balances change externally (ie holder repays, interest earned/charged), then the virtual reserves will get out-of-sync with real world +? alternate curves +? registry contract +? transparent proxy so AMM address can stay constant + +docs + high-level concept + how to setup and operate a maglev + interest costs + low-level detail of how system works for auditors + information for aggregators + how to maintain quotes off-chain, including tracking cash from VaultStatus logs of underlying vaults + +tests + prices + alternate decimals + choosing virtual reserves to stay below target LTVs + uniswap callback, flash swaps + hitting reserve/utilisation limits + changing reserves + changing fees/prices + onlyOwner methods can't be called by others From e2a8789c5c8d4b69bea14ef27c9ae9a82b69d789 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 03:09:27 -0500 Subject: [PATCH 008/312] todo --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 806767b..765da2c 100644 --- a/TODO +++ b/TODO @@ -3,6 +3,7 @@ * better error messages when exceeding virtual reserves * pause guardian ? re-sync reserves: if the vault balances change externally (ie holder repays, interest earned/charged), then the virtual reserves will get out-of-sync with real world + ? there is a race-condition when updating reserves: a swap could happen in between calculation and update ? alternate curves ? registry contract ? transparent proxy so AMM address can stay constant @@ -19,6 +20,7 @@ tests prices alternate decimals choosing virtual reserves to stay below target LTVs + when exchange rate in vaults != 1 uniswap callback, flash swaps hitting reserve/utilisation limits changing reserves From 8723318e9c7d7d0f50a5d90f422652a9eac09a6c Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 03:32:35 -0500 Subject: [PATCH 009/312] structured errors --- TODO | 1 - src/MaglevBase.sol | 7 +++++-- src/MaglevConstantSum.sol | 4 +++- test/ConstantSum.t.sol | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index 765da2c..3d3483e 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ * quoting should consider reserves, utilisation -* structured errors * better error messages when exceeding virtual reserves * pause guardian ? re-sync reserves: if the vault balances change externally (ie holder repays, interest earned/charged), then the virtual reserves will get out-of-sync with real world diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index a509fc0..15f0627 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -18,8 +18,11 @@ abstract contract MaglevBase is EVCUtil, Ownable { uint112 public reserve1; uint32 private locked; + error Reentrancy(); + error Overflow(); + modifier nonReentrant() { - require(locked == 0, "reentrancy"); + require(locked == 0, Reentrancy()); locked = 1; _; locked = 0; @@ -85,7 +88,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { uint256 newReserve0 = oldReserve0 + amount0In - amount0Out; uint256 newReserve1 = oldReserve1 + amount1In - amount1Out; - require(newReserve0 <= type(uint112).max && newReserve1 <= type(uint112).max, "overflow"); + require(newReserve0 <= type(uint112).max && newReserve1 <= type(uint112).max, Overflow()); verify(oldReserve0, oldReserve1, amount0In, amount1In, newReserve0, newReserve1); reserve0 = uint112(newReserve0); diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index b50f0e9..7572c38 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -8,6 +8,8 @@ contract MaglevConstantSum is MaglevBase { uint96 priceA; uint96 priceB; + error KNotSatisfied(); + struct ConstantSumParams { uint64 fee; uint96 priceA; @@ -38,7 +40,7 @@ contract MaglevConstantSum is MaglevBase { ) internal view virtual override { uint256 kBefore = k(oldReserve0, oldReserve1); uint256 kAfter = k(newReserve0 - (amount0In * fee / 1e18), newReserve1 - (amount1In * fee / 1e18)); - require(kAfter >= kBefore, "k not satisfied"); + require(kAfter >= kBefore, KNotSatisfied()); } // FIXME: quote functions should consider limits like reserve size and vault utilisation diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index fe2d1f8..46ca415 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -178,7 +178,7 @@ contract ConstantSumTest is EVaultTestBase { tt.transfer(address(maglev), needed - 2); - vm.expectRevert(bytes("k not satisfied")); + vm.expectRevert(Maglev.KNotSatisfied.selector); maglev.swap(a1, a2, recipient, ""); tt.transfer(address(maglev), 2); From 683f718df6d17b911a9c77828cb1f456cc4e4c60 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 04:11:44 -0500 Subject: [PATCH 010/312] reserves vs virtual reserves --- TODO | 2 -- src/MaglevBase.sol | 50 +++++++++++++++++++++++++++++++-------- src/MaglevConstantSum.sol | 6 ++--- test/ConstantSum.t.sol | 49 +++++++++++++++++++++++++++++++++++++- 4 files changed, 91 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index 3d3483e..2554e44 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,6 @@ * quoting should consider reserves, utilisation * better error messages when exceeding virtual reserves * pause guardian -? re-sync reserves: if the vault balances change externally (ie holder repays, interest earned/charged), then the virtual reserves will get out-of-sync with real world - ? there is a race-condition when updating reserves: a swap could happen in between calculation and update ? alternate curves ? registry contract ? transparent proxy so AMM address can stay constant diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 15f0627..d7ad4e6 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -18,6 +18,9 @@ abstract contract MaglevBase is EVCUtil, Ownable { uint112 public reserve1; uint32 private locked; + uint112 public virtualReserve0; + uint112 public virtualReserve1; + error Reentrancy(); error Overflow(); @@ -48,10 +51,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { } /// @dev Call *after* installing as operator - function configure(uint112 _reserve0, uint112 _reserve1) external onlyOwner { - reserve0 = _reserve0; - reserve1 = _reserve1; - + function configure() external onlyOwner { IERC20(asset0).approve(vault0, type(uint256).max); IERC20(asset1).approve(vault1, type(uint256).max); @@ -59,6 +59,15 @@ abstract contract MaglevBase is EVCUtil, Ownable { IEVC(evc).enableCollateral(myAccount, vault1); } + /// @dev Call whenever NAV changes significantly + function setVirtualReserves(uint112 _reserve0, uint112 _reserve1) external onlyOwner { + virtualReserve0 = _reserve0; + virtualReserve1 = _reserve1; + + reserve0 = adjustReserve(_reserve0, vault0); + reserve1 = adjustReserve(_reserve1, vault1); + } + function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external callThroughEVC @@ -96,13 +105,34 @@ abstract contract MaglevBase is EVCUtil, Ownable { } } - function withdrawAssets(address vault, uint256 amount, address to) internal { - uint256 balance; - { - uint256 shares = IEVault(vault).balanceOf(myAccount); - balance = shares == 0 ? 0 : IEVault(vault).convertToAssets(shares); + // Internal utilities + + function myDebt(address vault) internal view returns (uint256) { + return IEVault(vault).debtOf(myAccount); + } + + function myBalance(address vault) internal view returns (uint256) { + uint256 shares = IEVault(vault).balanceOf(myAccount); + return shares == 0 ? 0 : IEVault(vault).convertToAssets(shares); + } + + function adjustReserve(uint112 reserve, address vault) internal view returns (uint112) { + uint256 adjusted; + uint256 debt = myDebt(vault); + + if (debt != 0) { + adjusted = reserve > debt ? reserve - debt : 0; + } else { + adjusted = reserve + myBalance(vault); } + require(adjusted <= type(uint112).max, Overflow()); + return uint112(adjusted); + } + + function withdrawAssets(address vault, uint256 amount, address to) internal { + uint256 balance = myBalance(vault); + if (balance > 0) { uint256 a = amount < balance ? amount : balance; IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IERC4626.withdraw, (a, to, myAccount))); @@ -118,7 +148,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { function depositAssets(address vault, uint256 amount) internal { IEVault(vault).deposit(amount, myAccount); - uint256 debt = IEVault(vault).debtOf(myAccount); + uint256 debt = myDebt(vault); if (debt > 0) { IEVC(evc).call( diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index 7572c38..68db94a 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -4,9 +4,9 @@ pragma solidity ^0.8.0; import {MaglevBase} from "./MaglevBase.sol"; contract MaglevConstantSum is MaglevBase { - uint64 fee; - uint96 priceA; - uint96 priceB; + uint64 public fee; + uint96 public priceA; + uint96 public priceB; error KNotSatisfied(); diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index 46ca415..f2d9967 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -55,7 +55,10 @@ contract ConstantSumTest is EVaultTestBase { evc.setAccountOperator(holder, address(maglev), true); vm.prank(owner); - maglev.configure(100e18, 100e18); + maglev.configure(); + + vm.prank(owner); + maglev.setVirtualReserves(50e18, 50e18); } function _mintAndDeposit(address who, IEVault vault, uint256 amount) internal { @@ -92,6 +95,48 @@ contract ConstantSumTest is EVaultTestBase { logState(); } + function test_reserveLimit() public { + assertEq(maglev.virtualReserve0(), 50e18); + assertEq(maglev.virtualReserve1(), 50e18); + assertEq(maglev.reserve0(), 60e18); + assertEq(maglev.reserve1(), 60e18); + + assetTST.mint(address(this), 1000e18); + + uint256 snapshot = vm.snapshotState(); + + { + uint256 amount = 60.000001e18; + assetTST.transfer(address(maglev), amount); + vm.expectRevert(); // FIXME: which error? + maglev.swap(0, amount, address(this), ""); + } + + vm.revertToState(snapshot); + + { + uint256 amount = 60e18; + assetTST.transfer(address(maglev), amount); + maglev.swap(0, amount, address(this), ""); + } + + assertEq(eTST2.debtOf(holder), 50e18); + assertEq(maglev.reserve0(), 120e18); + assertEq(maglev.reserve1(), 0e18); + + vm.prank(owner); + maglev.setVirtualReserves(60e18, 55e18); + + assertEq(maglev.reserve0(), 130e18); + assertEq(maglev.reserve1(), 5e18); + + vm.prank(owner); + maglev.setVirtualReserves(40e18, 45e18); + + assertEq(maglev.reserve0(), 110e18); + assertEq(maglev.reserve1(), 0e18); + } + function test_basicSwapFuzz(uint256 amount1, uint256 amount2) public { amount1 = bound(amount1, 1e18, 25e18); amount2 = bound(amount2, 1e18, 50e18); @@ -117,6 +162,8 @@ contract ConstantSumTest is EVaultTestBase { console.log(" eTST Vault debt: ", eTST.debtOf(holder)); console.log(" eTST2 Vault assets: ", eTST2.convertToAssets(eTST2.balanceOf(holder))); console.log(" eTST2 Vault debt: ", eTST2.debtOf(holder)); + console.log(" reserve0: ", maglev.reserve0()); + console.log(" reserve1: ", maglev.reserve1()); } function test_quoteGivenIn() public { From fe58517b9b728574ef8922e1da43ec18b742d973 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 04:45:53 -0500 Subject: [PATCH 011/312] make quote functions consider limits such as reserves/utilisation --- TODO | 6 +++--- src/MaglevBase.sol | 41 +++++++++++++++++++++++++++++++++++---- src/MaglevConstantSum.sol | 6 ++---- test/ConstantSum.t.sol | 8 ++++---- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/TODO b/TODO index 2554e44..54def1e 100644 --- a/TODO +++ b/TODO @@ -8,15 +8,15 @@ docs high-level concept how to setup and operate a maglev + choosing virtual reserves to stay below target LTVs interest costs low-level detail of how system works for auditors information for aggregators how to maintain quotes off-chain, including tracking cash from VaultStatus logs of underlying vaults tests - prices - alternate decimals - choosing virtual reserves to stay below target LTVs + prices/alternate decimals + especially quoting when exchange rate in vaults != 1 uniswap callback, flash swaps hitting reserve/utilisation limits diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index d7ad4e6..59ab803 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -23,6 +23,9 @@ abstract contract MaglevBase is EVCUtil, Ownable { error Reentrancy(); error Overflow(); + error UnsupportedPair(); + error InsufficientReserves(); + error InsufficientCash(); modifier nonReentrant() { require(locked == 0, Reentrancy()); @@ -50,6 +53,8 @@ abstract contract MaglevBase is EVCUtil, Ownable { myAccount = params.myAccount; } + // Owner functions + /// @dev Call *after* installing as operator function configure() external onlyOwner { IERC20(asset0).approve(vault0, type(uint256).max); @@ -68,6 +73,8 @@ abstract contract MaglevBase is EVCUtil, Ownable { reserve1 = adjustReserve(_reserve1, vault1); } + // Swapper interface + function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external callThroughEVC @@ -105,6 +112,14 @@ abstract contract MaglevBase is EVCUtil, Ownable { } } + function quoteExactInput(address tokenIn, address tokenOut, uint256 amountIn) external view returns (uint256) { + return getQuote(tokenIn, tokenOut, amountIn, true); + } + + function quoteExactOutput(address tokenIn, address tokenOut, uint256 amountOut) external view returns (uint256) { + return getQuote(tokenIn, tokenOut, amountOut, false); + } + // Internal utilities function myDebt(address vault) internal view returns (uint256) { @@ -134,9 +149,9 @@ abstract contract MaglevBase is EVCUtil, Ownable { uint256 balance = myBalance(vault); if (balance > 0) { - uint256 a = amount < balance ? amount : balance; - IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IERC4626.withdraw, (a, to, myAccount))); - amount -= a; + uint256 avail = amount < balance ? amount : balance; + IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IERC4626.withdraw, (avail, to, myAccount))); + amount -= avail; } if (amount > 0) { @@ -161,7 +176,22 @@ abstract contract MaglevBase is EVCUtil, Ownable { } } - // Verification implemented by sub-class + function getQuote(address tokenIn, address tokenOut, uint256 amount, bool exactIn) internal view returns (uint256) { + bool asset0IsInput; + if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true; + else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; + else revert UnsupportedPair(); + + uint256 quote = exactIn ? quoteGivenIn(amount, asset0IsInput) : quoteGivenOut(amount, asset0IsInput); + + require(quote <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); + require(quote <= IERC20(asset0IsInput ? asset1 : asset0).balanceOf(asset0IsInput ? vault1 : vault0), InsufficientCash()); + + return quote; + } + + + // To be implemented by sub-class function verify( uint256 oldReserve0, @@ -171,4 +201,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { uint256 newReserve0, uint256 newReserve1 ) internal view virtual; + + function quoteGivenIn(uint256 amount, bool asset0IsInput) internal view virtual returns (uint256); + function quoteGivenOut(uint256 amount, bool asset0IsInput) internal view virtual returns (uint256); } diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index 68db94a..a09be8e 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -43,13 +43,11 @@ contract MaglevConstantSum is MaglevBase { require(kAfter >= kBefore, KNotSatisfied()); } - // FIXME: quote functions should consider limits like reserve size and vault utilisation - - function quoteGivenIn(uint256 amount, bool) public view returns (uint256) { + function quoteGivenIn(uint256 amount, bool) internal view virtual override returns (uint256) { return amount * (1e18 - fee) / 1e18; } - function quoteGivenOut(uint256 amount, bool) public view returns (uint256) { + function quoteGivenOut(uint256 amount, bool) internal view virtual override returns (uint256) { return amount * 1e18 / (1e18 - fee); } } diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index f2d9967..2ef277e 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -166,12 +166,12 @@ contract ConstantSumTest is EVaultTestBase { console.log(" reserve1: ", maglev.reserve1()); } - function test_quoteGivenIn() public { + function test_quoteExactInput() public { vm.prank(owner); maglev.setConstantSumParams(Maglev.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); assetTST.mint(address(this), 100e18); - uint256 q = maglev.quoteGivenIn(1e18, true); + uint256 q = maglev.quoteExactInput(address(assetTST), address(assetTST2), 1e18); assertLt(q, 1e18); assetTST.transfer(address(maglev), 1e18); @@ -179,13 +179,13 @@ contract ConstantSumTest is EVaultTestBase { assertEq(assetTST2.balanceOf(recipient), q); } - function test_quoteGivenOut() public { + function test_quoteExactOutput() public { vm.prank(owner); maglev.setConstantSumParams(Maglev.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); assetTST.mint(address(this), 100e18); - uint256 q = maglev.quoteGivenOut(1e18, true); + uint256 q = maglev.quoteExactOutput(address(assetTST), address(assetTST2), 1e18); assertGt(q, 1e18); assetTST.transfer(address(maglev), q); From e76170c69a15695064598312cab0f1bb7383f18a Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 05:11:39 -0500 Subject: [PATCH 012/312] todo --- TODO | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 54def1e..8b7243f 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,6 @@ -* quoting should consider reserves, utilisation -* better error messages when exceeding virtual reserves * pause guardian +* events + * reserve change on each swap ? alternate curves ? registry contract ? transparent proxy so AMM address can stay constant @@ -9,6 +9,7 @@ docs high-level concept how to setup and operate a maglev choosing virtual reserves to stay below target LTVs + when to update virtual reserves interest costs low-level detail of how system works for auditors information for aggregators From 85484fce0ac6218d3c8c93a748fb5db77993f761 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 05:11:45 -0500 Subject: [PATCH 013/312] fmt --- src/MaglevBase.sol | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 59ab803..8148176 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -65,12 +65,12 @@ abstract contract MaglevBase is EVCUtil, Ownable { } /// @dev Call whenever NAV changes significantly - function setVirtualReserves(uint112 _reserve0, uint112 _reserve1) external onlyOwner { - virtualReserve0 = _reserve0; - virtualReserve1 = _reserve1; + function setVirtualReserves(uint112 vr0, uint112 vr1) external onlyOwner { + virtualReserve0 = vr0; + virtualReserve1 = vr1; - reserve0 = adjustReserve(_reserve0, vault0); - reserve1 = adjustReserve(_reserve1, vault1); + reserve0 = adjustReserve(vr0, vault0); + reserve1 = adjustReserve(vr1, vault1); } // Swapper interface @@ -176,7 +176,11 @@ abstract contract MaglevBase is EVCUtil, Ownable { } } - function getQuote(address tokenIn, address tokenOut, uint256 amount, bool exactIn) internal view returns (uint256) { + function getQuote(address tokenIn, address tokenOut, uint256 amount, bool exactIn) + internal + view + returns (uint256) + { bool asset0IsInput; if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true; else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; @@ -185,12 +189,14 @@ abstract contract MaglevBase is EVCUtil, Ownable { uint256 quote = exactIn ? quoteGivenIn(amount, asset0IsInput) : quoteGivenOut(amount, asset0IsInput); require(quote <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); - require(quote <= IERC20(asset0IsInput ? asset1 : asset0).balanceOf(asset0IsInput ? vault1 : vault0), InsufficientCash()); + require( + quote <= IERC20(asset0IsInput ? asset1 : asset0).balanceOf(asset0IsInput ? vault1 : vault0), + InsufficientCash() + ); return quote; } - // To be implemented by sub-class function verify( From b0b4475e764750f613b70befdf9a4aeeda4b0aec Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 09:49:21 -0500 Subject: [PATCH 014/312] wip docs --- README.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 74f6d14..2a7100f 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,24 @@ -## Euler Maglev +# Euler Maglev ![maglev logo](docs/maglev.png) Maglev is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) as leveraged lending products in order to extend the range of its reserves and thereby improve the capital efficiency of liquidity provisioning. -It implements a conventional Uniswap2-style interface, but internally supports custom pricing curves and other advanced functionality. +To swappers, it presents a conventional Uniswap2-style interface but internally it supports custom pricing curves and other advanced functionality. + +## Concept + +Given a fixed size investment, Maglev aims to increase the size of trades that can be serviced, relative to a conventional AMM such as Uniswap. It does this by borrowing the "out token" and collateralising this loan with the received "in token". Later on, when somebody wishes to swap in the reverse direction, the loan can be repaid in exchange for receiving the collateral, unwinding the borrow position. + +Because the total size of the position can be many times larger than your initial investment (depending on how much LTV/leverage is allowed on the underlying lending pools), the swapping fees earned can be magnified. + +The down-side is that while the AMM holds this leveraged position, it is paying interest on the loan. Fortunately, this is partially compensated by the fact that the AMM is earning interest on the collateral. + +## Operation + +Since the level of acceptable borrowing risk may not be the same for every user, pooled deposits are not yet possible, and each Maglev instance manages funds for a single user (who of course may be a common enterprise). + +Maglev is contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators) ## License From 2233371197d333edd85812902dc4b4d688cd7a4e Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 13:59:38 -0500 Subject: [PATCH 015/312] updates --- README.md | 4 ++-- TODO | 1 + src/MaglevBase.sol | 21 ++++++++------------- src/MaglevConstantSum.sol | 16 ++++++++-------- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 2a7100f..9f418d7 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ The down-side is that while the AMM holds this leveraged position, it is paying ## Operation -Since the level of acceptable borrowing risk may not be the same for every user, pooled deposits are not yet possible, and each Maglev instance manages funds for a single user (who of course may be a common enterprise). +Since the level of acceptable borrowing risk may not be the same for every user, pooled deposits are not yet possible, and each Maglev instance manages funds for a single user (who of course may operate on behalf of pooled funds). -Maglev is contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators) +Maglev is contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators). This means that a user, known as a *holder*, does not give up control over their funds to a smart contract, but instead retains it in their wallet. The holder can be any compatible address, including standard multisig wallets or even a simple EOA. ## License diff --git a/TODO b/TODO index 8b7243f..070efb5 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,7 @@ * pause guardian * events * reserve change on each swap +* ConstantSum: incorporate price multipliers in quote methods ? alternate curves ? registry contract ? transparent proxy so AMM address can stay constant diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 8148176..b9c1296 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -99,13 +99,11 @@ abstract contract MaglevBase is EVCUtil, Ownable { // Verify curve invariant is satisified { - uint256 oldReserve0 = reserve0; - uint256 oldReserve1 = reserve1; - uint256 newReserve0 = oldReserve0 + amount0In - amount0Out; - uint256 newReserve1 = oldReserve1 + amount1In - amount1Out; + uint256 newReserve0 = reserve0 + amount0In - amount0Out; + uint256 newReserve1 = reserve1 + amount1In - amount1Out; require(newReserve0 <= type(uint112).max && newReserve1 <= type(uint112).max, Overflow()); - verify(oldReserve0, oldReserve1, amount0In, amount1In, newReserve0, newReserve1); + verify(amount0In, amount1In, newReserve0, newReserve1); reserve0 = uint112(newReserve0); reserve1 = uint112(newReserve1); @@ -113,11 +111,11 @@ abstract contract MaglevBase is EVCUtil, Ownable { } function quoteExactInput(address tokenIn, address tokenOut, uint256 amountIn) external view returns (uint256) { - return getQuote(tokenIn, tokenOut, amountIn, true); + return _computeQuote(tokenIn, tokenOut, amountIn, true); } function quoteExactOutput(address tokenIn, address tokenOut, uint256 amountOut) external view returns (uint256) { - return getQuote(tokenIn, tokenOut, amountOut, false); + return _computeQuote(tokenIn, tokenOut, amountOut, false); } // Internal utilities @@ -176,7 +174,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { } } - function getQuote(address tokenIn, address tokenOut, uint256 amount, bool exactIn) + function _computeQuote(address tokenIn, address tokenOut, uint256 amount, bool exactIn) internal view returns (uint256) @@ -186,7 +184,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; else revert UnsupportedPair(); - uint256 quote = exactIn ? quoteGivenIn(amount, asset0IsInput) : quoteGivenOut(amount, asset0IsInput); + uint256 quote = computeQuote(amount, exactIn, asset0IsInput); require(quote <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); require( @@ -200,14 +198,11 @@ abstract contract MaglevBase is EVCUtil, Ownable { // To be implemented by sub-class function verify( - uint256 oldReserve0, - uint256 oldReserve1, uint256 amount0In, uint256 amount1In, uint256 newReserve0, uint256 newReserve1 ) internal view virtual; - function quoteGivenIn(uint256 amount, bool asset0IsInput) internal view virtual returns (uint256); - function quoteGivenOut(uint256 amount, bool asset0IsInput) internal view virtual returns (uint256); + function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view virtual returns (uint256); } diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index a09be8e..bdbe3a6 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -31,23 +31,23 @@ contract MaglevConstantSum is MaglevBase { } function verify( - uint256 oldReserve0, - uint256 oldReserve1, uint256 amount0In, uint256 amount1In, uint256 newReserve0, uint256 newReserve1 ) internal view virtual override { - uint256 kBefore = k(oldReserve0, oldReserve1); + uint256 kBefore = k(reserve0, reserve1); uint256 kAfter = k(newReserve0 - (amount0In * fee / 1e18), newReserve1 - (amount1In * fee / 1e18)); require(kAfter >= kBefore, KNotSatisfied()); } - function quoteGivenIn(uint256 amount, bool) internal view virtual override returns (uint256) { - return amount * (1e18 - fee) / 1e18; - } + // FIXME: incorporate priceA and priceB - function quoteGivenOut(uint256 amount, bool) internal view virtual override returns (uint256) { - return amount * 1e18 / (1e18 - fee); + function computeQuote(uint256 amount, bool exactIn, bool) internal view virtual override returns (uint256) { + if (exactIn) { + return amount * (1e18 - fee) / 1e18; + } else { + return amount * 1e18 / (1e18 - fee); + } } } From 82e81983689436bb7e5f492c54174a33abdd4afb Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 14:33:50 -0500 Subject: [PATCH 016/312] test suite refactor --- test/ConstantSum.t.sol | 52 ++++------------------------------ test/MaglevTestBase.t.sol | 59 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 46 deletions(-) create mode 100644 test/MaglevTestBase.t.sol diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index 2ef277e..9a0071d 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -4,50 +4,21 @@ pragma solidity ^0.8.24; import {Test, console} from "forge-std/Test.sol"; -import {EVaultTestBase, TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; +import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; +import {MaglevTestBase} from "./MaglevTestBase.t.sol"; -import {MaglevBase, MaglevConstantSum as Maglev} from "../src/MaglevConstantSum.sol"; +import {MaglevConstantSum as Maglev} from "../src/MaglevConstantSum.sol"; -contract ConstantSumTest is EVaultTestBase { +contract ConstantSumTest is MaglevTestBase { Maglev public maglev; - address public depositor = makeAddr("depositor"); - address public owner = makeAddr("owner"); - address public holder = makeAddr("holder"); - address public recipient = makeAddr("recipient"); - - function setUp() public override { + function setUp() public override virtual { super.setUp(); - // Vault config - - eTST.setLTV(address(eTST2), 0.9e4, 0.9e4, 0); - eTST2.setLTV(address(eTST), 0.9e4, 0.9e4, 0); - - // Pricing - - oracle.setPrice(address(assetTST), unitOfAccount, 1e18); - oracle.setPrice(address(assetTST2), unitOfAccount, 1e18); - oracle.setPrice(address(eTST), unitOfAccount, 1e18); - oracle.setPrice(address(eTST2), unitOfAccount, 1e18); - - oracle.setPrice(address(assetTST), address(assetTST2), 1e18); - oracle.setPrice(address(assetTST2), address(assetTST), 1e18); - - // Funding - - _mintAndDeposit(depositor, eTST, 100e18); - _mintAndDeposit(depositor, eTST2, 100e18); - - _mintAndDeposit(holder, eTST, 10e18); - _mintAndDeposit(holder, eTST2, 10e18); - - // Setup Maglev - vm.prank(owner); maglev = new Maglev( - MaglevBase.BaseParams({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder}), + _getMaglevBaseParams(), Maglev.ConstantSumParams({fee: 0, priceA: 1, priceB: 1}) ); @@ -61,17 +32,6 @@ contract ConstantSumTest is EVaultTestBase { maglev.setVirtualReserves(50e18, 50e18); } - function _mintAndDeposit(address who, IEVault vault, uint256 amount) internal { - TestERC20 tok = TestERC20(vault.asset()); - tok.mint(who, amount); - - vm.prank(who); - tok.approve(address(vault), type(uint256).max); - - vm.prank(who); - vault.deposit(amount, who); - } - function test_basicSwapReport() public { uint256 amount = 25e18; assetTST.mint(address(this), amount); diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol new file mode 100644 index 0000000..4af5545 --- /dev/null +++ b/test/MaglevTestBase.t.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.24; + +import {Test, console} from "forge-std/Test.sol"; + +import {EVaultTestBase, TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; + +import {MaglevBase} from "../src/MaglevBase.sol"; + +contract MaglevTestBase is EVaultTestBase { + address public depositor = makeAddr("depositor"); + address public owner = makeAddr("owner"); + address public holder = makeAddr("holder"); + address public recipient = makeAddr("recipient"); + + function setUp() public override virtual { + super.setUp(); + + // Vault config + + eTST.setLTV(address(eTST2), 0.9e4, 0.9e4, 0); + eTST2.setLTV(address(eTST), 0.9e4, 0.9e4, 0); + + // Pricing + + oracle.setPrice(address(assetTST), unitOfAccount, 1e18); + oracle.setPrice(address(assetTST2), unitOfAccount, 1e18); + oracle.setPrice(address(eTST), unitOfAccount, 1e18); + oracle.setPrice(address(eTST2), unitOfAccount, 1e18); + + oracle.setPrice(address(assetTST), address(assetTST2), 1e18); + oracle.setPrice(address(assetTST2), address(assetTST), 1e18); + + // Funding + + _mintAndDeposit(depositor, eTST, 100e18); + _mintAndDeposit(depositor, eTST2, 100e18); + + _mintAndDeposit(holder, eTST, 10e18); + _mintAndDeposit(holder, eTST2, 10e18); + } + + function _getMaglevBaseParams() internal view returns (MaglevBase.BaseParams memory) { + return MaglevBase.BaseParams({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder}); + } + + function _mintAndDeposit(address who, IEVault vault, uint256 amount) internal { + TestERC20 tok = TestERC20(vault.asset()); + tok.mint(who, amount); + + vm.prank(who); + tok.approve(address(vault), type(uint256).max); + + vm.prank(who); + vault.deposit(amount, who); + } +} From 5dcb7f1d4781e5434fa0f0ecde7edeccb4fbc3dc Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 15:17:29 -0500 Subject: [PATCH 017/312] constant product --- src/MaglevConstantProduct.sol | 50 +++++++++++++++++++++ test/ConstantProduct.t.sol | 83 +++++++++++++++++++++++++++++++++++ test/ConstantSum.t.sol | 18 ++------ test/MaglevTestBase.t.sol | 12 +++++ 4 files changed, 148 insertions(+), 15 deletions(-) create mode 100644 src/MaglevConstantProduct.sol create mode 100644 test/ConstantProduct.t.sol diff --git a/src/MaglevConstantProduct.sol b/src/MaglevConstantProduct.sol new file mode 100644 index 0000000..18b47a5 --- /dev/null +++ b/src/MaglevConstantProduct.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {MaglevBase} from "./MaglevBase.sol"; + +contract MaglevConstantProduct is MaglevBase { + uint64 public fee; + + error KNotSatisfied(); + + struct ConstantProductParams { + uint64 fee; + } + + constructor(BaseParams memory baseParams, ConstantProductParams memory params) MaglevBase(baseParams) { + setConstantProductParams(params); + } + + function setConstantProductParams(ConstantProductParams memory params) public onlyOwner { + fee = params.fee; + } + + function k(uint256 r0, uint256 r1) public pure returns (uint256) { + return r0 * r1; + } + + function verify( + uint256 amount0In, + uint256 amount1In, + uint256 newReserve0, + uint256 newReserve1 + ) internal view virtual override { + uint256 kBefore = k(reserve0, reserve1); + uint256 kAfter = k(newReserve0 - (amount0In * fee / 1e18), newReserve1 - (amount1In * fee / 1e18)); + require(kAfter >= kBefore, KNotSatisfied()); + } + + // FIXME: incorporate priceA and priceB + + function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view virtual override returns (uint256) { + uint256 reserveIn = asset0IsInput ? reserve0 : reserve1; + uint256 reserveOut = asset0IsInput ? reserve1 : reserve0; + + if (exactIn) { + return (reserveOut * amount) / (reserveIn + amount) * (1e18 - fee) / 1e18; + } else { + return (reserveIn * amount) / (reserveOut - amount) * 1e18 / (1e18 - fee); + } + } +} diff --git a/test/ConstantProduct.t.sol b/test/ConstantProduct.t.sol new file mode 100644 index 0000000..30c2be6 --- /dev/null +++ b/test/ConstantProduct.t.sol @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.24; + +import {Test, console} from "forge-std/Test.sol"; + +import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; +import {MaglevTestBase} from "./MaglevTestBase.t.sol"; + +import {MaglevConstantProduct as Maglev} from "../src/MaglevConstantProduct.sol"; + +contract ConstantProductTest is MaglevTestBase { + Maglev public maglev; + + function setUp() public override virtual { + super.setUp(); + + vm.prank(owner); + maglev = new Maglev( + _getMaglevBaseParams(), + Maglev.ConstantProductParams({fee: 0}) + ); + + vm.prank(holder); + evc.setAccountOperator(holder, address(maglev), true); + + vm.prank(owner); + maglev.configure(); + + vm.prank(owner); + maglev.setVirtualReserves(50e18, 50e18); + } + + function test_fee_exactIn(uint256 amount, bool dir) public { + amount = bound(amount, 0.1e18, 25e18); + + TestERC20 t1; + TestERC20 t2; + if (dir) (t1, t2) = (assetTST, assetTST2); + else (t1, t2) = (assetTST2, assetTST); + + t1.mint(address(this), amount); + + uint256 qOrig = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount); + + vm.prank(owner); + maglev.setConstantProductParams(Maglev.ConstantProductParams({fee: 0.002e18})); + + uint256 q = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount); + assertApproxEqAbs(1e18 * q / qOrig, 0.998e18, 0.000000000001e18); + + t1.transfer(address(maglev), amount); + if (dir) maglev.swap(0, q, address(this), ""); + else maglev.swap(q, 0, address(this), ""); + assertEq(t2.balanceOf(address(this)), q); + } + + function test_pathIndependent(uint256 amount, bool dir) public { + amount = bound(amount, 0.1e18, 25e18); + + TestERC20 t1; + TestERC20 t2; + if (dir) (t1, t2) = (assetTST, assetTST2); + else (t1, t2) = (assetTST2, assetTST); + + t1.mint(address(this), amount); + + uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount); + + t1.transfer(address(maglev), amount); + if (dir) maglev.swap(0, q, address(this), ""); + else maglev.swap(q, 0, address(this), ""); + assertEq(t2.balanceOf(address(this)), q); + + t2.transfer(address(maglev), q); + if (dir) maglev.swap(amount - 2, 0, address(this), ""); // - 2 due to rounding + else maglev.swap(0, amount - 2, address(this), ""); + + uint256 q2 = maglev.quoteExactInput(address(t1), address(t2), amount); + assertApproxEqAbs(q, q2, 2); + } +} diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index 9a0071d..514a576 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -36,13 +36,13 @@ contract ConstantSumTest is MaglevTestBase { uint256 amount = 25e18; assetTST.mint(address(this), amount); - logState(); + logState(address(maglev)); assetTST.transfer(address(maglev), amount); maglev.swap(0, amount, address(this), ""); assertEq(assetTST2.balanceOf(address(this)), amount); - logState(); + logState(address(maglev)); uint256 amount2 = 50e18; assetTST2.mint(address(this), amount2); @@ -52,7 +52,7 @@ contract ConstantSumTest is MaglevTestBase { assetTST2.transfer(address(maglev), 1e18); maglev.swap(1e18, 0, address(this), ""); - logState(); + logState(address(maglev)); } function test_reserveLimit() public { @@ -114,18 +114,6 @@ contract ConstantSumTest is MaglevTestBase { assertEq(assetTST2.balanceOf(address(this)), amount1); } - function logState() internal view { - console.log("--------------------"); - console.log("Account States:"); - console.log("HOLDER"); - console.log(" eTST Vault assets: ", eTST.convertToAssets(eTST.balanceOf(holder))); - console.log(" eTST Vault debt: ", eTST.debtOf(holder)); - console.log(" eTST2 Vault assets: ", eTST2.convertToAssets(eTST2.balanceOf(holder))); - console.log(" eTST2 Vault debt: ", eTST2.debtOf(holder)); - console.log(" reserve0: ", maglev.reserve0()); - console.log(" reserve1: ", maglev.reserve1()); - } - function test_quoteExactInput() public { vm.prank(owner); maglev.setConstantSumParams(Maglev.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index 4af5545..fad890a 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -56,4 +56,16 @@ contract MaglevTestBase is EVaultTestBase { vm.prank(who); vault.deposit(amount, who); } + + function logState(address ml) internal view { + console.log("--------------------"); + console.log("Account States:"); + console.log("HOLDER"); + console.log(" eTST Vault assets: ", eTST.convertToAssets(eTST.balanceOf(holder))); + console.log(" eTST Vault debt: ", eTST.debtOf(holder)); + console.log(" eTST2 Vault assets: ", eTST2.convertToAssets(eTST2.balanceOf(holder))); + console.log(" eTST2 Vault debt: ", eTST2.debtOf(holder)); + console.log(" reserve0: ", MaglevBase(ml).reserve0()); + console.log(" reserve1: ", MaglevBase(ml).reserve1()); + } } From 2fca61f314d836d79859ad19ccfa2f2979492cc0 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 15:17:46 -0500 Subject: [PATCH 018/312] fmt --- src/MaglevBase.sol | 10 ++++------ src/MaglevConstantProduct.sol | 20 +++++++++++++------- src/MaglevConstantSum.sol | 12 ++++++------ test/ConstantProduct.t.sol | 8 +++----- test/ConstantSum.t.sol | 7 ++----- test/MaglevTestBase.t.sol | 5 +++-- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index b9c1296..9e4f70b 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -197,12 +197,10 @@ abstract contract MaglevBase is EVCUtil, Ownable { // To be implemented by sub-class - function verify( - uint256 amount0In, - uint256 amount1In, - uint256 newReserve0, - uint256 newReserve1 - ) internal view virtual; + function verify(uint256 amount0In, uint256 amount1In, uint256 newReserve0, uint256 newReserve1) + internal + view + virtual; function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view virtual returns (uint256); } diff --git a/src/MaglevConstantProduct.sol b/src/MaglevConstantProduct.sol index 18b47a5..4020bdc 100644 --- a/src/MaglevConstantProduct.sol +++ b/src/MaglevConstantProduct.sol @@ -24,12 +24,12 @@ contract MaglevConstantProduct is MaglevBase { return r0 * r1; } - function verify( - uint256 amount0In, - uint256 amount1In, - uint256 newReserve0, - uint256 newReserve1 - ) internal view virtual override { + function verify(uint256 amount0In, uint256 amount1In, uint256 newReserve0, uint256 newReserve1) + internal + view + virtual + override + { uint256 kBefore = k(reserve0, reserve1); uint256 kAfter = k(newReserve0 - (amount0In * fee / 1e18), newReserve1 - (amount1In * fee / 1e18)); require(kAfter >= kBefore, KNotSatisfied()); @@ -37,7 +37,13 @@ contract MaglevConstantProduct is MaglevBase { // FIXME: incorporate priceA and priceB - function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view virtual override returns (uint256) { + function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) + internal + view + virtual + override + returns (uint256) + { uint256 reserveIn = asset0IsInput ? reserve0 : reserve1; uint256 reserveOut = asset0IsInput ? reserve1 : reserve0; diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index bdbe3a6..5c03d32 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -30,12 +30,12 @@ contract MaglevConstantSum is MaglevBase { return (r0 * priceA) + (r1 * priceB); } - function verify( - uint256 amount0In, - uint256 amount1In, - uint256 newReserve0, - uint256 newReserve1 - ) internal view virtual override { + function verify(uint256 amount0In, uint256 amount1In, uint256 newReserve0, uint256 newReserve1) + internal + view + virtual + override + { uint256 kBefore = k(reserve0, reserve1); uint256 kAfter = k(newReserve0 - (amount0In * fee / 1e18), newReserve1 - (amount1In * fee / 1e18)); require(kAfter >= kBefore, KNotSatisfied()); diff --git a/test/ConstantProduct.t.sol b/test/ConstantProduct.t.sol index 30c2be6..41c8c28 100644 --- a/test/ConstantProduct.t.sol +++ b/test/ConstantProduct.t.sol @@ -13,14 +13,11 @@ import {MaglevConstantProduct as Maglev} from "../src/MaglevConstantProduct.sol" contract ConstantProductTest is MaglevTestBase { Maglev public maglev; - function setUp() public override virtual { + function setUp() public virtual override { super.setUp(); vm.prank(owner); - maglev = new Maglev( - _getMaglevBaseParams(), - Maglev.ConstantProductParams({fee: 0}) - ); + maglev = new Maglev(_getMaglevBaseParams(), Maglev.ConstantProductParams({fee: 0})); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); @@ -75,6 +72,7 @@ contract ConstantProductTest is MaglevTestBase { t2.transfer(address(maglev), q); if (dir) maglev.swap(amount - 2, 0, address(this), ""); // - 2 due to rounding + else maglev.swap(0, amount - 2, address(this), ""); uint256 q2 = maglev.quoteExactInput(address(t1), address(t2), amount); diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index 514a576..a9957bf 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -13,14 +13,11 @@ import {MaglevConstantSum as Maglev} from "../src/MaglevConstantSum.sol"; contract ConstantSumTest is MaglevTestBase { Maglev public maglev; - function setUp() public override virtual { + function setUp() public virtual override { super.setUp(); vm.prank(owner); - maglev = new Maglev( - _getMaglevBaseParams(), - Maglev.ConstantSumParams({fee: 0, priceA: 1, priceB: 1}) - ); + maglev = new Maglev(_getMaglevBaseParams(), Maglev.ConstantSumParams({fee: 0, priceA: 1, priceB: 1})); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index fad890a..b1df01c 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -15,7 +15,7 @@ contract MaglevTestBase is EVaultTestBase { address public holder = makeAddr("holder"); address public recipient = makeAddr("recipient"); - function setUp() public override virtual { + function setUp() public virtual override { super.setUp(); // Vault config @@ -43,7 +43,8 @@ contract MaglevTestBase is EVaultTestBase { } function _getMaglevBaseParams() internal view returns (MaglevBase.BaseParams memory) { - return MaglevBase.BaseParams({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder}); + return + MaglevBase.BaseParams({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder}); } function _mintAndDeposit(address who, IEVault vault, uint256 amount) internal { From 68b2a31ddafee7d4a90225ab509d490135879856 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 16:40:18 -0500 Subject: [PATCH 019/312] docs --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/README.md b/README.md index 9f418d7..159b227 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,52 @@ Since the level of acceptable borrowing risk may not be the same for every user, Maglev is contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators). This means that a user, known as a *holder*, does not give up control over their funds to a smart contract, but instead retains it in their wallet. The holder can be any compatible address, including standard multisig wallets or even a simple EOA. +### Usage + +The following are the high-level steps required to use Maglev: + +* Deposit funds into one or both of the vaults +* Deploy the desired Maglev contract, choosing parameters such as the two vaults, and the desired `fee` +* Calculate the desired [virtual reserves](#virtual-reserves) and set these values by invoking `setVirtualReserves()` +* Install the Maglev contract as an operator for your account +* Invoke the `configure()` function on the Maglev contract + +At this point, anyone can invoke `swap()` on the Maglev contract, and this will perform borrowing and transferring activity between the two vaults. + +### Virtual Reserves + +The initial deposits in the vaults represent the initial investment, and are swapped back and forth in response to swapping activity. In a conventional AMM such as Uniswap, these balance are called *reserves*. However, if swapping was constrained to these assets alone, then this would imply a hard limit on the size of swaps that can be serviced. To increase the effective funds, Maglev AMMs are configured with *virtual reserves*. These are typically larger than the size of the conventional reserves, which signifies that not only can all the assets be swapped from one vault to another, but even more assets can be borrowed on the Maglev's account. + +Virtual reserves control the maximum debt that the Maglev contract will attempt to acquire on each of its two vaults. Each vault can be configured independently. + +For example, if the initial investment has a NAV of $1000, and virtual reserves are configured at $5000 for each vault, then the maximum LTV loan that the AMM will support will be `5000/6000 = 0.8333`. In order to leave a safety buffer, it is recommended to select a maximum LTV that is below the borrowing LTV of the vault. + +Note that it depends on the [curve] if the maximum LTV can actually be achieved. A constant product will only approach these reserve levels asymptotically, since each unit will get more and more expensive. However, with constant sum, this LTV can be achieved directly. + +### Desynchronised Virtual Reserves + +The Maglev contract tracks what it believes the reserves to be by caching their values in storage. These reserves are updated on each swap. However, since the balance is not actually held by the Maglev contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest is accrued, or suddenly if the holder moves funds or the position is liquidated. + +When this occurs, the `syncVirtualReserves()` should be invoked. This determines the actual balances (and debts) of the holder, and adjusts them by the configured virtual reserve levels. + + + +## Curves + +### Constant Sum + +This "curve" simply adds the values of the two reserves together and ensures that after a swap this sum has not decreased. This curve is mostly suitable for assets that are pegged to the same value, such as stable/stable pairs. + +This curve supports a price fraction so that the two tokens can have different relative values, which can be useful if the peg is other than 1:1, or if the tokens have differing decimals. + +In this curve, the entire virtual reserves can be consumed, and since each marginal unit of the swap has the same price, there is no direct incentive to deleverage the position. However, for the same reason this does allow fixed fees for swaps of any allowed size (fixed price impact). + +### Constant Product + +This is the traditional Uniswap2 curve that preserves the product of the two reserves. The larger a swap, the higher the price impact. Furthermore, the more profitable it is to arbitrage a disbalanced pool back to its wider market price. + + + ## License (c) 2024 Euler Labs Ltd. From d1f1af3d857014c6baa556f751267e96474676c2 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 16:40:23 -0500 Subject: [PATCH 020/312] TODO --- TODO | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/TODO b/TODO index 070efb5..3f3156c 100644 --- a/TODO +++ b/TODO @@ -7,12 +7,8 @@ ? transparent proxy so AMM address can stay constant docs - high-level concept - how to setup and operate a maglev - choosing virtual reserves to stay below target LTVs - when to update virtual reserves - interest costs low-level detail of how system works for auditors + how to add a curve information for aggregators how to maintain quotes off-chain, including tracking cash from VaultStatus logs of underlying vaults From 31d792cbd2aa3a176eba1ceb5b39163463135ba7 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 16:40:32 -0500 Subject: [PATCH 021/312] syncVirtualReserves method --- src/MaglevBase.sol | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 9e4f70b..5b762ea 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -64,13 +64,17 @@ abstract contract MaglevBase is EVCUtil, Ownable { IEVC(evc).enableCollateral(myAccount, vault1); } - /// @dev Call whenever NAV changes significantly function setVirtualReserves(uint112 vr0, uint112 vr1) external onlyOwner { virtualReserve0 = vr0; virtualReserve1 = vr1; - reserve0 = adjustReserve(vr0, vault0); - reserve1 = adjustReserve(vr1, vault1); + syncVirtualReserves(); + } + + /// @dev Call whenever underlying balances change externally + function syncVirtualReserves() public onlyOwner { + reserve0 = adjustReserve(virtualReserve0, vault0); + reserve1 = adjustReserve(virtualReserve1, vault1); } // Swapper interface From 24ad55b44132c5868f839a2e67c48fb153319665 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 16:41:33 -0500 Subject: [PATCH 022/312] TOC --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 159b227..8c48871 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,22 @@ Maglev is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs. To swappers, it presents a conventional Uniswap2-style interface but internally it supports custom pricing curves and other advanced functionality. + + + + +* [Concept](#concept) +* [Operation](#operation) + * [Usage](#usage) + * [Virtual Reserves](#virtual-reserves) + * [Desynchronised Virtual Reserves](#desynchronised-virtual-reserves) +* [Curves](#curves) + * [Constant Sum](#constant-sum) + * [Constant Product](#constant-product) +* [License](#license) + + + ## Concept Given a fixed size investment, Maglev aims to increase the size of trades that can be serviced, relative to a conventional AMM such as Uniswap. It does this by borrowing the "out token" and collateralising this loan with the received "in token". Later on, when somebody wishes to swap in the reverse direction, the loan can be repaid in exchange for receiving the collateral, unwinding the borrow position. From 5a2e30a706a02f192534d4866f88d214b68558ac Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 16:43:45 -0500 Subject: [PATCH 023/312] docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c48871..b4bb7eb 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Virtual reserves control the maximum debt that the Maglev contract will attempt For example, if the initial investment has a NAV of $1000, and virtual reserves are configured at $5000 for each vault, then the maximum LTV loan that the AMM will support will be `5000/6000 = 0.8333`. In order to leave a safety buffer, it is recommended to select a maximum LTV that is below the borrowing LTV of the vault. -Note that it depends on the [curve] if the maximum LTV can actually be achieved. A constant product will only approach these reserve levels asymptotically, since each unit will get more and more expensive. However, with constant sum, this LTV can be achieved directly. +Note that it depends on the [curve](#curves) if the maximum LTV can actually be achieved. A constant product will only approach these reserve levels asymptotically, since each unit will get more and more expensive. However, with constant sum, this LTV can be achieved directly. ### Desynchronised Virtual Reserves From fb6236ccac7470cc4cae33b73c341a605173cff5 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 16:57:46 -0500 Subject: [PATCH 024/312] copy pasta --- src/MaglevConstantProduct.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/MaglevConstantProduct.sol b/src/MaglevConstantProduct.sol index 4020bdc..62f8a01 100644 --- a/src/MaglevConstantProduct.sol +++ b/src/MaglevConstantProduct.sol @@ -35,8 +35,6 @@ contract MaglevConstantProduct is MaglevBase { require(kAfter >= kBefore, KNotSatisfied()); } - // FIXME: incorporate priceA and priceB - function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view From 7a31a7f7c142a52f77f31c5fdbe8f9467f2b9819 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 3 Dec 2024 18:02:42 -0500 Subject: [PATCH 025/312] docs --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b4bb7eb..e2aabee 100644 --- a/README.md +++ b/README.md @@ -28,20 +28,20 @@ Given a fixed size investment, Maglev aims to increase the size of trades that c Because the total size of the position can be many times larger than your initial investment (depending on how much LTV/leverage is allowed on the underlying lending pools), the swapping fees earned can be magnified. -The down-side is that while the AMM holds this leveraged position, it is paying interest on the loan. Fortunately, this is partially compensated by the fact that the AMM is earning interest on the collateral. +The down-side is that while the AMM holds this leveraged position, it is paying interest on the loan. Fortunately, this is partially compensated by the fact that the AMM is earning interest on the collateral. In addition, points and rewards may be earned on collateral/borrows. ## Operation Since the level of acceptable borrowing risk may not be the same for every user, pooled deposits are not yet possible, and each Maglev instance manages funds for a single user (who of course may operate on behalf of pooled funds). -Maglev is contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators). This means that a user, known as a *holder*, does not give up control over their funds to a smart contract, but instead retains it in their wallet. The holder can be any compatible address, including standard multisig wallets or even a simple EOA. +Maglev is a contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators). This means that the user, known as the *holder*, does not give up control over their funds to a smart contract, but instead retains it in their wallet. The holder can be any compatible address, including standard multisig wallets or even an EOA. ### Usage The following are the high-level steps required to use Maglev: * Deposit funds into one or both of the vaults -* Deploy the desired Maglev contract, choosing parameters such as the two vaults, and the desired `fee` +* Deploy the desired Maglev contract, choosing parameters such as the vaults and the desired `fee` * Calculate the desired [virtual reserves](#virtual-reserves) and set these values by invoking `setVirtualReserves()` * Install the Maglev contract as an operator for your account * Invoke the `configure()` function on the Maglev contract @@ -78,7 +78,7 @@ In this curve, the entire virtual reserves can be consumed, and since each margi ### Constant Product -This is the traditional Uniswap2 curve that preserves the product of the two reserves. The larger a swap, the higher the price impact. Furthermore, the more profitable it is to arbitrage a disbalanced pool back to its wider market price. +This is the traditional Uniswap2 curve that preserves the product of the two reserves. The larger a swap, the higher the price impact and the more profitable it is to arbitrage a disbalanced pool back to its wider market price. From f7259ffee6ad13b945b6da8520dd72a892d0d9c5 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 4 Dec 2024 17:14:37 -0500 Subject: [PATCH 026/312] wip --- src/MaglevEulerSwap.sol | 149 ++++++++++++++++++++++++++++++++++++++++ test/EulerSwap.t.sol | 43 ++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 src/MaglevEulerSwap.sol create mode 100644 test/EulerSwap.t.sol diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol new file mode 100644 index 0000000..820c368 --- /dev/null +++ b/src/MaglevEulerSwap.sol @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {console} from "forge-std/Test.sol"; +import {MaglevBase} from "./MaglevBase.sol"; + +contract MaglevEulerSwap is MaglevBase { + + error KNotSatisfied(); + + struct EulerSwapParams { + uint256 junk; + } + + constructor(BaseParams memory baseParams, EulerSwapParams memory params) MaglevBase(baseParams) { + setEulerSwapParams(params); + } + + function setEulerSwapParams(EulerSwapParams memory params) public onlyOwner { + } + + function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) + internal + view + virtual + override + { + uint256 px = 1e18; + uint256 py = 1e18; + uint256 cx = 0.40e18; + uint256 cy = 0.85e18; + require(_verify(newReserve0, newReserve1, px, py, virtualReserve0, virtualReserve1, cx, cy), KNotSatisfied()); + } + + function computeQuote(uint256, bool, bool) + internal + view + virtual + override + returns (uint256) + { + return 0; + } + + + + ///// + + function fx(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){ + require(xt > 0, "Reserves must be greater than zero"); + if (xt <= x0) { + return fx1(xt, px, py, x0, y0, cx, cy); + } else { + return fx2(xt, px, py, x0, y0, cx, cy); + } + } + + function fx1(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){ + require(xt <= x0, "Invalid input coordinate"); + return y0 + px * 1e18 / py * (cx * (2 * x0 - xt) / 1e18 + (1e18 - cx) * x0 / 1e18 * x0 / xt - x0) / 1e18; + } + + function fx2(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){ + require(xt > x0, "Invalid input coordinate"); + // intermediate values for solving quadratic equation + uint a = cy; + int b = (int(px) * 1e18 / int(py)) * (int(xt) - int(x0)) / 1e18 + int(y0) * (1e18 - 2 * int(cy)) / 1e18; + int c = (int(cy) - 1e18) * int(y0)**2 / 1e18 / 1e18; + uint discriminant = uint(int(uint(b**2) / 1e18) - 4 * int(a) * int(c) / 1e18); + uint numerator = uint(-b + int(uint(sqrt(discriminant) * 1e9))); + uint denominator = 2 * a; + return numerator * 1e18 / denominator; + } + + function fy(uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){ + require(yt > 0, "Reserves must be greater than zero"); + if (yt <= y0) { + return fx1(yt, py, px, y0, x0, cy, cx); + } else { + return fx2(yt, py, px, y0, x0, cy, cx); + } + } + + + function swap(int dx, int dy, uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (int, int) { + int xtNew = int(xt); + int ytNew = int(yt); + + if (dx != 0) { + xtNew += dx; + ytNew = int(fx(uint(xtNew), px, py, x0, y0, cx, cy)); + } + if (dy != 0) { + ytNew += dy; + xtNew = int(fy(uint(ytNew), px, py, x0, y0, cx, cy)); + } + dx = xtNew - int(xt); + dy = ytNew - int(yt); + + // // check invariant + // let invariantPassed = invariantCheck(xtNew, ytNew, parameters); + + return (dx, dy); + } + + function _verify(uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (bool){ + bool passed = false; + int delta = 0; + if(xt >= x0) { + delta = int(xt) - int(fy(yt, px, py, x0, y0, cx, cy)); + console.log("xt: ", int(xt)); + console.log("fy: ", int(fy(yt, px, py, x0, y0, cx, cy))); + } else { + delta = int(yt) - int(fx(xt, px, py, x0, y0, cx, cy)); + console.log("yt: ", int(yt)); + console.log("fx: ", int(fx(xt, px, py, x0, y0, cx, cy))); + } + + if (delta >= 0) { + // if distance is > zero, then point is above the curve, and invariant passes + passed = true; + } + return passed; + } + + function sqrt(uint256 x) public pure returns (uint128) { + if (x == 0) return 0; + else{ + uint256 xx = x; + uint256 r = 1; + if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; } + if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; } + if (xx >= 0x100000000) { xx >>= 32; r <<= 16; } + if (xx >= 0x10000) { xx >>= 16; r <<= 8; } + if (xx >= 0x100) { xx >>= 8; r <<= 4; } + if (xx >= 0x10) { xx >>= 4; r <<= 2; } + if (xx >= 0x8) { r <<= 1; } + r = (r + x / r) >> 1; + r = (r + x / r) >> 1; + r = (r + x / r) >> 1; + r = (r + x / r) >> 1; + r = (r + x / r) >> 1; + r = (r + x / r) >> 1; + r = (r + x / r) >> 1; + uint256 r1 = x / r; + return uint128 (r < r1 ? r : r1); + } + } +} diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol new file mode 100644 index 0000000..3ccb872 --- /dev/null +++ b/test/EulerSwap.t.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.24; + +import {Test, console} from "forge-std/Test.sol"; + +import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; +import {MaglevTestBase} from "./MaglevTestBase.t.sol"; + +import {MaglevEulerSwap as Maglev} from "../src/MaglevEulerSwap.sol"; + +contract EulerSwapTest is MaglevTestBase { + Maglev public maglev; + + function setUp() public virtual override { + super.setUp(); + + vm.prank(owner); + maglev = new Maglev(_getMaglevBaseParams(), Maglev.EulerSwapParams({junk: 0})); + + vm.prank(holder); + evc.setAccountOperator(holder, address(maglev), true); + + vm.prank(owner); + maglev.configure(); + + vm.prank(owner); + maglev.setVirtualReserves(50e18, 50e18); + } + + function test_basicSwap() public { + uint256 amountIn = 1e18; + uint256 amountOut = 0.3e18; + + assetTST.mint(address(this), amountIn); + + assetTST.transfer(address(maglev), amountIn); + maglev.swap(0, amountOut, address(this), ""); + + assertEq(assetTST2.balanceOf(address(this)), amountOut); + } +} From 117b76bdf6b1ea1d615993e2a919451dea3d07c2 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Thu, 5 Dec 2024 11:46:57 -0500 Subject: [PATCH 027/312] wip --- src/MaglevBase.sol | 3 +++ src/MaglevEulerSwap.sol | 5 +++++ test/EulerSwap.t.sol | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 5b762ea..42b7dc0 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -69,6 +69,9 @@ abstract contract MaglevBase is EVCUtil, Ownable { virtualReserve1 = vr1; syncVirtualReserves(); + + virtualReserve0 = reserve0; + virtualReserve1 = reserve1; } /// @dev Call whenever underlying balances change externally diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index 820c368..20b126a 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -29,6 +29,11 @@ contract MaglevEulerSwap is MaglevBase { uint256 py = 1e18; uint256 cx = 0.40e18; uint256 cy = 0.85e18; + + //require(_verify(49e18, 51e18, px, py, 50e18, 50e18, cx, cy), KNotSatisfied()); + + console.log("QQ", newReserve0, newReserve1); + console.log("ZZ", virtualReserve0, virtualReserve1); require(_verify(newReserve0, newReserve1, px, py, virtualReserve0, virtualReserve1, cx, cy), KNotSatisfied()); } diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 3ccb872..7758876 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -31,7 +31,7 @@ contract EulerSwapTest is MaglevTestBase { function test_basicSwap() public { uint256 amountIn = 1e18; - uint256 amountOut = 0.3e18; + uint256 amountOut = 0.9999999e18; assetTST.mint(address(this), amountIn); From 55b3fa7f8b52d55cea501e21809354fd9e320429 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Thu, 5 Dec 2024 22:09:32 -0500 Subject: [PATCH 028/312] wip --- src/MaglevBase.sol | 22 ++++++---------------- src/MaglevEulerSwap.sol | 4 ++-- test/ConstantProduct.t.sol | 2 +- test/ConstantSum.t.sol | 32 +++++++++++++++++++++++++------- test/EulerSwap.t.sol | 4 ++-- 5 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 42b7dc0..8c727e9 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; +import {console} from "forge-std/Test.sol"; import {Ownable, Context} from "openzeppelin-contracts/access/Ownable.sol"; import {EVCUtil} from "evc/utils/EVCUtil.sol"; import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; @@ -18,8 +19,8 @@ abstract contract MaglevBase is EVCUtil, Ownable { uint112 public reserve1; uint32 private locked; - uint112 public virtualReserve0; - uint112 public virtualReserve1; + uint112 public initialReserve0; + uint112 public initialReserve1; error Reentrancy(); error Overflow(); @@ -64,20 +65,9 @@ abstract contract MaglevBase is EVCUtil, Ownable { IEVC(evc).enableCollateral(myAccount, vault1); } - function setVirtualReserves(uint112 vr0, uint112 vr1) external onlyOwner { - virtualReserve0 = vr0; - virtualReserve1 = vr1; - - syncVirtualReserves(); - - virtualReserve0 = reserve0; - virtualReserve1 = reserve1; - } - - /// @dev Call whenever underlying balances change externally - function syncVirtualReserves() public onlyOwner { - reserve0 = adjustReserve(virtualReserve0, vault0); - reserve1 = adjustReserve(virtualReserve1, vault1); + function setDebtLimit(uint112 debtLimit0, uint112 debtLimit1) external onlyOwner { + reserve0 = initialReserve0 = adjustReserve(debtLimit0, vault0); + reserve1 = initialReserve1 = adjustReserve(debtLimit1, vault1); } // Swapper interface diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index 20b126a..f6b3ff1 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -33,8 +33,8 @@ contract MaglevEulerSwap is MaglevBase { //require(_verify(49e18, 51e18, px, py, 50e18, 50e18, cx, cy), KNotSatisfied()); console.log("QQ", newReserve0, newReserve1); - console.log("ZZ", virtualReserve0, virtualReserve1); - require(_verify(newReserve0, newReserve1, px, py, virtualReserve0, virtualReserve1, cx, cy), KNotSatisfied()); + console.log("ZZ", initialReserve0, initialReserve1); + require(_verify(newReserve0, newReserve1, px, py, initialReserve0, initialReserve1, cx, cy), KNotSatisfied()); } function computeQuote(uint256, bool, bool) diff --git a/test/ConstantProduct.t.sol b/test/ConstantProduct.t.sol index 41c8c28..7b7910a 100644 --- a/test/ConstantProduct.t.sol +++ b/test/ConstantProduct.t.sol @@ -26,7 +26,7 @@ contract ConstantProductTest is MaglevTestBase { maglev.configure(); vm.prank(owner); - maglev.setVirtualReserves(50e18, 50e18); + maglev.setDebtLimit(50e18, 50e18); } function test_fee_exactIn(uint256 amount, bool dir) public { diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index a9957bf..a36bd7b 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -26,7 +26,7 @@ contract ConstantSumTest is MaglevTestBase { maglev.configure(); vm.prank(owner); - maglev.setVirtualReserves(50e18, 50e18); + maglev.setDebtLimit(50e18, 50e18); } function test_basicSwapReport() public { @@ -53,8 +53,8 @@ contract ConstantSumTest is MaglevTestBase { } function test_reserveLimit() public { - assertEq(maglev.virtualReserve0(), 50e18); - assertEq(maglev.virtualReserve1(), 50e18); + assertEq(maglev.initialReserve0(), 60e18); + assertEq(maglev.initialReserve1(), 60e18); assertEq(maglev.reserve0(), 60e18); assertEq(maglev.reserve1(), 60e18); @@ -77,21 +77,39 @@ contract ConstantSumTest is MaglevTestBase { maglev.swap(0, amount, address(this), ""); } + assertEq(eTST.balanceOf(holder), 70e18); assertEq(eTST2.debtOf(holder), 50e18); assertEq(maglev.reserve0(), 120e18); assertEq(maglev.reserve1(), 0e18); + // Same debt limit means reserves not affected + + vm.prank(owner); + maglev.setDebtLimit(50e18, 50e18); + assertEq(maglev.reserve0(), 120e18); + assertEq(maglev.reserve1(), 0e18); + + // Increase debt limit on one side + vm.prank(owner); - maglev.setVirtualReserves(60e18, 55e18); + maglev.setDebtLimit(50e18, 55e18); + assertEq(maglev.reserve0(), 120e18); + assertEq(maglev.reserve1(), 5e18); + + // And the other - assertEq(maglev.reserve0(), 130e18); + vm.prank(owner); + maglev.setDebtLimit(55e18, 55e18); + assertEq(maglev.reserve0(), 125e18); assertEq(maglev.reserve1(), 5e18); + // Shrink debt limit + vm.prank(owner); - maglev.setVirtualReserves(40e18, 45e18); + maglev.setDebtLimit(40e18, 45e18); assertEq(maglev.reserve0(), 110e18); - assertEq(maglev.reserve1(), 0e18); + assertEq(maglev.reserve1(), 0e18); // can't go below 0 } function test_basicSwapFuzz(uint256 amount1, uint256 amount2) public { diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 7758876..818979f 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -26,12 +26,12 @@ contract EulerSwapTest is MaglevTestBase { maglev.configure(); vm.prank(owner); - maglev.setVirtualReserves(50e18, 50e18); + maglev.setDebtLimit(50e18, 50e18); } function test_basicSwap() public { uint256 amountIn = 1e18; - uint256 amountOut = 0.9999999e18; + uint256 amountOut = 0.99e18; assetTST.mint(address(this), amountIn); From 97cf8e9c2ff96d13a1c4c633bd4b4f364a843407 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 6 Dec 2024 23:59:46 -0500 Subject: [PATCH 029/312] sqrt fix --- src/MaglevEulerSwap.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index f6b3ff1..8c7c90b 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -71,8 +71,8 @@ contract MaglevEulerSwap is MaglevBase { uint a = cy; int b = (int(px) * 1e18 / int(py)) * (int(xt) - int(x0)) / 1e18 + int(y0) * (1e18 - 2 * int(cy)) / 1e18; int c = (int(cy) - 1e18) * int(y0)**2 / 1e18 / 1e18; - uint discriminant = uint(int(uint(b**2) / 1e18) - 4 * int(a) * int(c) / 1e18); - uint numerator = uint(-b + int(uint(sqrt(discriminant) * 1e9))); + uint discriminant = uint(int(uint(b**2)) - 4 * int(a) * int(c)); + uint numerator = uint(-b + int(uint(sqrt(discriminant)))); uint denominator = 2 * a; return numerator * 1e18 / denominator; } From 5bff38611abd2052159d1723f84e358238d528f9 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 7 Dec 2024 01:13:20 -0500 Subject: [PATCH 030/312] quoting --- src/MaglevEulerSwap.sol | 88 +++++++++++++++++++++++++---------------- test/EulerSwap.t.sol | 36 ++++++++++++++++- 2 files changed, 88 insertions(+), 36 deletions(-) diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index 8c7c90b..ccef8c7 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -5,11 +5,18 @@ import {console} from "forge-std/Test.sol"; import {MaglevBase} from "./MaglevBase.sol"; contract MaglevEulerSwap is MaglevBase { + uint256 public _px; + uint256 public _py; + uint256 public _cx; + uint256 public _cy; error KNotSatisfied(); struct EulerSwapParams { - uint256 junk; + uint256 px; + uint256 py; + uint256 cx; + uint256 cy; } constructor(BaseParams memory baseParams, EulerSwapParams memory params) MaglevBase(baseParams) { @@ -17,6 +24,10 @@ contract MaglevEulerSwap is MaglevBase { } function setEulerSwapParams(EulerSwapParams memory params) public onlyOwner { + _px = params.px; + _py = params.py; + _cx = params.cx; + _cy = params.cy; } function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) @@ -25,33 +36,51 @@ contract MaglevEulerSwap is MaglevBase { virtual override { - uint256 px = 1e18; - uint256 py = 1e18; - uint256 cx = 0.40e18; - uint256 cy = 0.85e18; - - //require(_verify(49e18, 51e18, px, py, 50e18, 50e18, cx, cy), KNotSatisfied()); - - console.log("QQ", newReserve0, newReserve1); - console.log("ZZ", initialReserve0, initialReserve1); - require(_verify(newReserve0, newReserve1, px, py, initialReserve0, initialReserve1, cx, cy), KNotSatisfied()); + require(verifyCurve(newReserve0, newReserve1, _px, _py, initialReserve0, initialReserve1, _cx, _cy), KNotSatisfied()); } - function computeQuote(uint256, bool, bool) + uint256 private constant roundingCompensation = 1.0000000000001e18; + + function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view virtual override returns (uint256) { - return 0; + int dx; + int dy; + + if (exactIn) { + if (asset0IsInput) dx = int(amount); + else dy = int(amount); + } else { + if (asset0IsInput) dy = -int(amount); + else dx = -int(amount); + } + + (dx, dy) = simulateSwap(dx, dy, reserve0, reserve1, _px, _py, initialReserve0, initialReserve1, _cx, _cy); + + uint output; + + if (exactIn) { + if (asset0IsInput) output = uint(-dy); + else output = uint(-dx); + output = output * 1e18 / roundingCompensation; + } else { + if (asset0IsInput) output = uint(dx); + else output = uint(dy); + output = output * roundingCompensation / 1e18; + } + + return output; } ///// - function fx(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){ + function fx(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) internal pure returns (uint){ require(xt > 0, "Reserves must be greater than zero"); if (xt <= x0) { return fx1(xt, px, py, x0, y0, cx, cy); @@ -60,12 +89,12 @@ contract MaglevEulerSwap is MaglevBase { } } - function fx1(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){ + function fx1(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint) internal pure returns (uint){ require(xt <= x0, "Invalid input coordinate"); return y0 + px * 1e18 / py * (cx * (2 * x0 - xt) / 1e18 + (1e18 - cx) * x0 / 1e18 * x0 / xt - x0) / 1e18; } - function fx2(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){ + function fx2(uint xt, uint px, uint py, uint x0, uint y0, uint, uint cy) internal pure returns (uint){ require(xt > x0, "Invalid input coordinate"); // intermediate values for solving quadratic equation uint a = cy; @@ -77,7 +106,7 @@ contract MaglevEulerSwap is MaglevBase { return numerator * 1e18 / denominator; } - function fy(uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (uint){ + function fy(uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) internal pure returns (uint){ require(yt > 0, "Reserves must be greater than zero"); if (yt <= y0) { return fx1(yt, py, px, y0, x0, cy, cx); @@ -87,7 +116,7 @@ contract MaglevEulerSwap is MaglevBase { } - function swap(int dx, int dy, uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (int, int) { + function simulateSwap(int dx, int dy, uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) internal pure returns (int, int) { int xtNew = int(xt); int ytNew = int(yt); @@ -102,33 +131,24 @@ contract MaglevEulerSwap is MaglevBase { dx = xtNew - int(xt); dy = ytNew - int(yt); - // // check invariant - // let invariantPassed = invariantCheck(xtNew, ytNew, parameters); - return (dx, dy); } - function _verify(uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) public pure returns (bool){ - bool passed = false; + function verifyCurve(uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) internal pure returns (bool){ int delta = 0; - if(xt >= x0) { + + if (xt >= x0) { delta = int(xt) - int(fy(yt, px, py, x0, y0, cx, cy)); - console.log("xt: ", int(xt)); - console.log("fy: ", int(fy(yt, px, py, x0, y0, cx, cy))); } else { delta = int(yt) - int(fx(xt, px, py, x0, y0, cx, cy)); - console.log("yt: ", int(yt)); - console.log("fx: ", int(fx(xt, px, py, x0, y0, cx, cy))); } - if (delta >= 0) { - // if distance is > zero, then point is above the curve, and invariant passes - passed = true; - } - return passed; + // if distance is > zero, then point is above the curve, and invariant passes + return (delta >= 0); } - function sqrt(uint256 x) public pure returns (uint128) { + // EIP-7054 + function sqrt(uint256 x) internal pure returns (uint128) { if (x == 0) return 0; else{ uint256 xx = x; diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 818979f..512cc3b 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -17,7 +17,12 @@ contract EulerSwapTest is MaglevTestBase { super.setUp(); vm.prank(owner); - maglev = new Maglev(_getMaglevBaseParams(), Maglev.EulerSwapParams({junk: 0})); + maglev = new Maglev(_getMaglevBaseParams(), Maglev.EulerSwapParams({ + px: 1e18, + py: 1e18, + cx: 0.40e18, + cy: 0.85e18 + })); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); @@ -31,7 +36,7 @@ contract EulerSwapTest is MaglevTestBase { function test_basicSwap() public { uint256 amountIn = 1e18; - uint256 amountOut = 0.99e18; + uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); assetTST.mint(address(this), amountIn); @@ -40,4 +45,31 @@ contract EulerSwapTest is MaglevTestBase { assertEq(assetTST2.balanceOf(address(this)), amountOut); } + + + function test_pathIndependent(uint256 amount, bool dir) public { + amount = bound(amount, 0.1e18, 25e18); + + TestERC20 t1; + TestERC20 t2; + if (dir) (t1, t2) = (assetTST, assetTST2); + else (t1, t2) = (assetTST2, assetTST); + + t1.mint(address(this), amount); + + uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount); + + t1.transfer(address(maglev), amount); + if (dir) maglev.swap(0, q, address(this), ""); + else maglev.swap(q, 0, address(this), ""); + assertEq(t2.balanceOf(address(this)), q); + + t2.transfer(address(maglev), q); + if (dir) maglev.swap(amount - 2, 0, address(this), ""); // - 2 due to rounding + + else maglev.swap(0, amount - 2, address(this), ""); + + uint256 q2 = maglev.quoteExactInput(address(t1), address(t2), amount); + assertApproxEqAbs(q, q2, 0.00000001e18); + } } From f9efe921074a5a3325fc965eb9630b42c51d648a Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 7 Dec 2024 01:15:36 -0500 Subject: [PATCH 031/312] fmt --- src/MaglevEulerSwap.sol | 151 ++++++++++++++++++++++++++-------------- test/EulerSwap.t.sol | 9 +-- 2 files changed, 100 insertions(+), 60 deletions(-) diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index ccef8c7..bd9d95c 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -30,13 +30,10 @@ contract MaglevEulerSwap is MaglevBase { _cy = params.cy; } - function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) - internal - view - virtual - override - { - require(verifyCurve(newReserve0, newReserve1, _px, _py, initialReserve0, initialReserve1, _cx, _cy), KNotSatisfied()); + function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) internal view virtual override { + require( + verifyCurve(newReserve0, newReserve1, _px, _py, initialReserve0, initialReserve1, _cx, _cy), KNotSatisfied() + ); } uint256 private constant roundingCompensation = 1.0000000000001e18; @@ -48,39 +45,41 @@ contract MaglevEulerSwap is MaglevBase { override returns (uint256) { - int dx; - int dy; + int256 dx; + int256 dy; if (exactIn) { - if (asset0IsInput) dx = int(amount); - else dy = int(amount); + if (asset0IsInput) dx = int256(amount); + else dy = int256(amount); } else { - if (asset0IsInput) dy = -int(amount); - else dx = -int(amount); + if (asset0IsInput) dy = -int256(amount); + else dx = -int256(amount); } (dx, dy) = simulateSwap(dx, dy, reserve0, reserve1, _px, _py, initialReserve0, initialReserve1, _cx, _cy); - uint output; + uint256 output; if (exactIn) { - if (asset0IsInput) output = uint(-dy); - else output = uint(-dx); + if (asset0IsInput) output = uint256(-dy); + else output = uint256(-dx); output = output * 1e18 / roundingCompensation; } else { - if (asset0IsInput) output = uint(dx); - else output = uint(dy); + if (asset0IsInput) output = uint256(dx); + else output = uint256(dy); output = output * roundingCompensation / 1e18; } return output; } - - ///// - function fx(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) internal pure returns (uint){ + function fx(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) + internal + pure + returns (uint256) + { require(xt > 0, "Reserves must be greater than zero"); if (xt <= x0) { return fx1(xt, px, py, x0, y0, cx, cy); @@ -89,24 +88,37 @@ contract MaglevEulerSwap is MaglevBase { } } - function fx1(uint xt, uint px, uint py, uint x0, uint y0, uint cx, uint) internal pure returns (uint){ + function fx1(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256) + internal + pure + returns (uint256) + { require(xt <= x0, "Invalid input coordinate"); return y0 + px * 1e18 / py * (cx * (2 * x0 - xt) / 1e18 + (1e18 - cx) * x0 / 1e18 * x0 / xt - x0) / 1e18; } - function fx2(uint xt, uint px, uint py, uint x0, uint y0, uint, uint cy) internal pure returns (uint){ + function fx2(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256, uint256 cy) + internal + pure + returns (uint256) + { require(xt > x0, "Invalid input coordinate"); // intermediate values for solving quadratic equation - uint a = cy; - int b = (int(px) * 1e18 / int(py)) * (int(xt) - int(x0)) / 1e18 + int(y0) * (1e18 - 2 * int(cy)) / 1e18; - int c = (int(cy) - 1e18) * int(y0)**2 / 1e18 / 1e18; - uint discriminant = uint(int(uint(b**2)) - 4 * int(a) * int(c)); - uint numerator = uint(-b + int(uint(sqrt(discriminant)))); - uint denominator = 2 * a; + uint256 a = cy; + int256 b = (int256(px) * 1e18 / int256(py)) * (int256(xt) - int256(x0)) / 1e18 + + int256(y0) * (1e18 - 2 * int256(cy)) / 1e18; + int256 c = (int256(cy) - 1e18) * int256(y0) ** 2 / 1e18 / 1e18; + uint256 discriminant = uint256(int256(uint256(b ** 2)) - 4 * int256(a) * int256(c)); + uint256 numerator = uint256(-b + int256(uint256(sqrt(discriminant)))); + uint256 denominator = 2 * a; return numerator * 1e18 / denominator; } - function fy(uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) internal pure returns (uint){ + function fy(uint256 yt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) + internal + pure + returns (uint256) + { require(yt > 0, "Reserves must be greater than zero"); if (yt <= y0) { return fx1(yt, py, px, y0, x0, cy, cx); @@ -115,51 +127,84 @@ contract MaglevEulerSwap is MaglevBase { } } - - function simulateSwap(int dx, int dy, uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) internal pure returns (int, int) { - int xtNew = int(xt); - int ytNew = int(yt); + function simulateSwap( + int256 dx, + int256 dy, + uint256 xt, + uint256 yt, + uint256 px, + uint256 py, + uint256 x0, + uint256 y0, + uint256 cx, + uint256 cy + ) internal pure returns (int256, int256) { + int256 xtNew = int256(xt); + int256 ytNew = int256(yt); if (dx != 0) { xtNew += dx; - ytNew = int(fx(uint(xtNew), px, py, x0, y0, cx, cy)); + ytNew = int256(fx(uint256(xtNew), px, py, x0, y0, cx, cy)); } if (dy != 0) { ytNew += dy; - xtNew = int(fy(uint(ytNew), px, py, x0, y0, cx, cy)); + xtNew = int256(fy(uint256(ytNew), px, py, x0, y0, cx, cy)); } - dx = xtNew - int(xt); - dy = ytNew - int(yt); + dx = xtNew - int256(xt); + dy = ytNew - int256(yt); return (dx, dy); } - function verifyCurve(uint xt, uint yt, uint px, uint py, uint x0, uint y0, uint cx, uint cy) internal pure returns (bool){ - int delta = 0; + function verifyCurve(uint256 xt, uint256 yt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) + internal + pure + returns (bool) + { + int256 delta = 0; if (xt >= x0) { - delta = int(xt) - int(fy(yt, px, py, x0, y0, cx, cy)); + delta = int256(xt) - int256(fy(yt, px, py, x0, y0, cx, cy)); } else { - delta = int(yt) - int(fx(xt, px, py, x0, y0, cx, cy)); + delta = int256(yt) - int256(fx(xt, px, py, x0, y0, cx, cy)); } - + // if distance is > zero, then point is above the curve, and invariant passes return (delta >= 0); } // EIP-7054 function sqrt(uint256 x) internal pure returns (uint128) { - if (x == 0) return 0; - else{ + if (x == 0) { + return 0; + } else { uint256 xx = x; uint256 r = 1; - if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; } - if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; } - if (xx >= 0x100000000) { xx >>= 32; r <<= 16; } - if (xx >= 0x10000) { xx >>= 16; r <<= 8; } - if (xx >= 0x100) { xx >>= 8; r <<= 4; } - if (xx >= 0x10) { xx >>= 4; r <<= 2; } - if (xx >= 0x8) { r <<= 1; } + if (xx >= 0x100000000000000000000000000000000) { + xx >>= 128; + r <<= 64; + } + if (xx >= 0x10000000000000000) { + xx >>= 64; + r <<= 32; + } + if (xx >= 0x100000000) { + xx >>= 32; + r <<= 16; + } + if (xx >= 0x10000) { + xx >>= 16; + r <<= 8; + } + if (xx >= 0x100) { + xx >>= 8; + r <<= 4; + } + if (xx >= 0x10) { + xx >>= 4; + r <<= 2; + } + if (xx >= 0x8) r <<= 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; @@ -168,7 +213,7 @@ contract MaglevEulerSwap is MaglevBase { r = (r + x / r) >> 1; r = (r + x / r) >> 1; uint256 r1 = x / r; - return uint128 (r < r1 ? r : r1); + return uint128(r < r1 ? r : r1); } } } diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 512cc3b..b772d17 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -17,12 +17,8 @@ contract EulerSwapTest is MaglevTestBase { super.setUp(); vm.prank(owner); - maglev = new Maglev(_getMaglevBaseParams(), Maglev.EulerSwapParams({ - px: 1e18, - py: 1e18, - cx: 0.40e18, - cy: 0.85e18 - })); + maglev = + new Maglev(_getMaglevBaseParams(), Maglev.EulerSwapParams({px: 1e18, py: 1e18, cx: 0.4e18, cy: 0.85e18})); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); @@ -46,7 +42,6 @@ contract EulerSwapTest is MaglevTestBase { assertEq(assetTST2.balanceOf(address(this)), amountOut); } - function test_pathIndependent(uint256 amount, bool dir) public { amount = bound(amount, 0.1e18, 25e18); From 561c50ea38d80b9cf57a59bea1faebecc2364e6b Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 7 Dec 2024 10:13:19 -0500 Subject: [PATCH 032/312] nav fuzz testing --- test/EulerSwap.t.sol | 43 ++++++++++++++++++++++++++++++++++++++- test/MaglevTestBase.t.sol | 12 +++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index b772d17..7bd0017 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -61,10 +61,51 @@ contract EulerSwapTest is MaglevTestBase { t2.transfer(address(maglev), q); if (dir) maglev.swap(amount - 2, 0, address(this), ""); // - 2 due to rounding - else maglev.swap(0, amount - 2, address(this), ""); uint256 q2 = maglev.quoteExactInput(address(t1), address(t2), amount); assertApproxEqAbs(q, q2, 0.00000001e18); } + + function test_fuzzParams(uint256 amount, uint256 amount2, uint256 px, uint256 py, uint256 cx, uint256 cy, bool dir) public { + amount = bound(amount, 0.1e18, 25e18); + amount2 = bound(amount2, 0.1e18, 25e18); + px = bound(px, 1e18, 1e18); + py = bound(py, 1e18, 1e18); + cx = bound(cx, 0.01e18, 0.99e18); + cy = bound(cy, 0.01e18, 0.99e18); + + int256 origNav = getHolderNAV(); + + vm.prank(owner); + maglev.setEulerSwapParams(Maglev.EulerSwapParams({ + px: px, + py: py, + cx: cx, + cy: cy + })); + + TestERC20 t1; + TestERC20 t2; + if (dir) (t1, t2) = (assetTST, assetTST2); + else (t1, t2) = (assetTST2, assetTST); + + t1.mint(address(this), amount); + uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount); + + t1.transfer(address(maglev), amount); + if (dir) maglev.swap(0, q, address(this), ""); + else maglev.swap(q, 0, address(this), ""); + assertEq(t2.balanceOf(address(this)), q); + + t2.mint(address(this), amount2); + uint256 q2 = maglev.quoteExactInput(address(t2), address(t1), amount2); + + t2.transfer(address(maglev), amount2); + if (dir) maglev.swap(q2, 0, address(this), ""); + else maglev.swap(0, q2, address(this), ""); + assertEq(t1.balanceOf(address(this)), q2); + + assertGe(getHolderNAV(), origNav); + } } diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index b1df01c..c7e96d2 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -58,6 +58,18 @@ contract MaglevTestBase is EVaultTestBase { vault.deposit(amount, who); } + 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 int(balValue) - int(debtValue); + } + function logState(address ml) internal view { console.log("--------------------"); console.log("Account States:"); From 635a8df259c5ccb65b9d7f80fefd361e11896704 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sun, 8 Dec 2024 01:07:31 -0500 Subject: [PATCH 033/312] pricing tests --- test/ConstantProduct.t.sol | 4 ++-- test/ConstantSum.t.sol | 12 +++++----- test/EulerSwap.t.sol | 47 ++++++++++++++++++++++++++++++++------ test/MaglevTestBase.t.sol | 8 +++++++ 4 files changed, 56 insertions(+), 15 deletions(-) diff --git a/test/ConstantProduct.t.sol b/test/ConstantProduct.t.sol index 7b7910a..f93e60f 100644 --- a/test/ConstantProduct.t.sol +++ b/test/ConstantProduct.t.sol @@ -29,7 +29,7 @@ contract ConstantProductTest is MaglevTestBase { maglev.setDebtLimit(50e18, 50e18); } - function test_fee_exactIn(uint256 amount, bool dir) public { + function test_fee_exactIn(uint256 amount, bool dir) public monotonicHolderNAV { amount = bound(amount, 0.1e18, 25e18); TestERC20 t1; @@ -53,7 +53,7 @@ contract ConstantProductTest is MaglevTestBase { assertEq(t2.balanceOf(address(this)), q); } - function test_pathIndependent(uint256 amount, bool dir) public { + function test_pathIndependent(uint256 amount, bool dir) public monotonicHolderNAV { amount = bound(amount, 0.1e18, 25e18); TestERC20 t1; diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index a36bd7b..d9609ab 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -29,7 +29,7 @@ contract ConstantSumTest is MaglevTestBase { maglev.setDebtLimit(50e18, 50e18); } - function test_basicSwapReport() public { + function test_basicSwapReport() public monotonicHolderNAV { uint256 amount = 25e18; assetTST.mint(address(this), amount); @@ -52,7 +52,7 @@ contract ConstantSumTest is MaglevTestBase { logState(address(maglev)); } - function test_reserveLimit() public { + function test_reserveLimit() public monotonicHolderNAV { assertEq(maglev.initialReserve0(), 60e18); assertEq(maglev.initialReserve1(), 60e18); assertEq(maglev.reserve0(), 60e18); @@ -112,7 +112,7 @@ contract ConstantSumTest is MaglevTestBase { assertEq(maglev.reserve1(), 0e18); // can't go below 0 } - function test_basicSwapFuzz(uint256 amount1, uint256 amount2) public { + function test_basicSwapFuzz(uint256 amount1, uint256 amount2) public monotonicHolderNAV { amount1 = bound(amount1, 1e18, 25e18); amount2 = bound(amount2, 1e18, 50e18); @@ -129,7 +129,7 @@ contract ConstantSumTest is MaglevTestBase { assertEq(assetTST2.balanceOf(address(this)), amount1); } - function test_quoteExactInput() public { + function test_quoteExactInput() public monotonicHolderNAV { vm.prank(owner); maglev.setConstantSumParams(Maglev.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); @@ -142,7 +142,7 @@ contract ConstantSumTest is MaglevTestBase { assertEq(assetTST2.balanceOf(recipient), q); } - function test_quoteExactOutput() public { + function test_quoteExactOutput() public monotonicHolderNAV { vm.prank(owner); maglev.setConstantSumParams(Maglev.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); @@ -156,7 +156,7 @@ contract ConstantSumTest is MaglevTestBase { assertEq(assetTST2.balanceOf(recipient), 1e18); } - function test_fees(uint256 fee, uint256 amount1, bool token0) public { + function test_fees(uint256 fee, uint256 amount1, bool token0) public monotonicHolderNAV { fee = bound(fee, 0, 0.02e18); amount1 = bound(amount1, 1e18, 25e18); diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 7bd0017..abb7941 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -30,7 +30,7 @@ contract EulerSwapTest is MaglevTestBase { maglev.setDebtLimit(50e18, 50e18); } - function test_basicSwap() public { + function test_basicSwap() public monotonicHolderNAV { uint256 amountIn = 1e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); @@ -42,7 +42,36 @@ contract EulerSwapTest is MaglevTestBase { assertEq(assetTST2.balanceOf(address(this)), amountOut); } - function test_pathIndependent(uint256 amount, bool dir) public { + function test_price() public { + uint price = 0.5e18; + uint px = price; + uint py = 1e18; + oracle.setPrice(address(eTST), unitOfAccount, 0.5e18); + oracle.setPrice(address(assetTST), unitOfAccount, 0.5e18); + + int256 origNAV = getHolderNAV(); + + vm.prank(owner); + maglev.setEulerSwapParams(Maglev.EulerSwapParams({ + px: px, + py: py, + cx: 0.4e18, + cy: 0.85e18 + })); + + uint256 amountIn = 1e18; + uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); + + assetTST.mint(address(this), amountIn); + + assetTST.transfer(address(maglev), amountIn); + maglev.swap(0, amountOut, address(this), ""); + assertEq(assetTST2.balanceOf(address(this)), amountOut); + + assertGe(getHolderNAV(), origNAV); + } + + function test_pathIndependent(uint256 amount, bool dir) public monotonicHolderNAV { amount = bound(amount, 0.1e18, 25e18); TestERC20 t1; @@ -67,15 +96,17 @@ contract EulerSwapTest is MaglevTestBase { assertApproxEqAbs(q, q2, 0.00000001e18); } - function test_fuzzParams(uint256 amount, uint256 amount2, uint256 px, uint256 py, uint256 cx, uint256 cy, bool dir) public { + function test_fuzzParams(uint256 amount, uint256 amount2, uint256 price, uint256 cx, uint256 cy, bool dir) public { amount = bound(amount, 0.1e18, 25e18); amount2 = bound(amount2, 0.1e18, 25e18); - px = bound(px, 1e18, 1e18); - py = bound(py, 1e18, 1e18); + price = bound(price, 0.1e18, 10e18); cx = bound(cx, 0.01e18, 0.99e18); cy = bound(cy, 0.01e18, 0.99e18); - int256 origNav = getHolderNAV(); + uint px = price; + uint py = 1e18; + oracle.setPrice(address(eTST), unitOfAccount, price); + oracle.setPrice(address(assetTST), unitOfAccount, price); vm.prank(owner); maglev.setEulerSwapParams(Maglev.EulerSwapParams({ @@ -85,6 +116,8 @@ contract EulerSwapTest is MaglevTestBase { cy: cy })); + int256 origNAV = getHolderNAV(); + TestERC20 t1; TestERC20 t2; if (dir) (t1, t2) = (assetTST, assetTST2); @@ -106,6 +139,6 @@ contract EulerSwapTest is MaglevTestBase { else maglev.swap(0, q2, address(this), ""); assertEq(t1.balanceOf(address(this)), q2); - assertGe(getHolderNAV(), origNav); + assertGe(getHolderNAV(), origNAV); } } diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index c7e96d2..67e8020 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -63,6 +63,8 @@ contract MaglevTestBase is EVaultTestBase { uint256 debt0 = eTST.debtOf(holder); uint256 balance1 = eTST2.convertToAssets(eTST2.balanceOf(holder)); uint256 debt1 = eTST2.debtOf(holder); + console.log("V0",balance0,debt0); + console.log("V1",balance1,debt1); 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); @@ -70,6 +72,12 @@ contract MaglevTestBase is EVaultTestBase { return int(balValue) - int(debtValue); } + modifier monotonicHolderNAV() { + int256 orig = getHolderNAV(); + _; + assertGe(getHolderNAV(), orig); + } + function logState(address ml) internal view { console.log("--------------------"); console.log("Account States:"); From f59f99a6429ff6aac9cdf1e7a5e202e16afa66da Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sun, 8 Dec 2024 01:30:54 -0500 Subject: [PATCH 034/312] cleanup --- test/MaglevTestBase.t.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index 67e8020..7db8146 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -63,8 +63,6 @@ contract MaglevTestBase is EVaultTestBase { uint256 debt0 = eTST.debtOf(holder); uint256 balance1 = eTST2.convertToAssets(eTST2.balanceOf(holder)); uint256 debt1 = eTST2.debtOf(holder); - console.log("V0",balance0,debt0); - console.log("V1",balance1,debt1); 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); From f3910f1cac988f13a79a78473036fe0522dc62a8 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sun, 8 Dec 2024 01:32:34 -0500 Subject: [PATCH 035/312] fmt --- test/EulerSwap.t.sol | 25 ++++++++----------------- test/MaglevTestBase.t.sol | 8 +++++--- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index abb7941..8aa07cd 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -43,21 +43,16 @@ contract EulerSwapTest is MaglevTestBase { } function test_price() public { - uint price = 0.5e18; - uint px = price; - uint py = 1e18; + uint256 price = 0.5e18; + uint256 px = price; + uint256 py = 1e18; oracle.setPrice(address(eTST), unitOfAccount, 0.5e18); oracle.setPrice(address(assetTST), unitOfAccount, 0.5e18); int256 origNAV = getHolderNAV(); vm.prank(owner); - maglev.setEulerSwapParams(Maglev.EulerSwapParams({ - px: px, - py: py, - cx: 0.4e18, - cy: 0.85e18 - })); + maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: 0.4e18, cy: 0.85e18})); uint256 amountIn = 1e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); @@ -90,6 +85,7 @@ contract EulerSwapTest is MaglevTestBase { t2.transfer(address(maglev), q); if (dir) maglev.swap(amount - 2, 0, address(this), ""); // - 2 due to rounding + else maglev.swap(0, amount - 2, address(this), ""); uint256 q2 = maglev.quoteExactInput(address(t1), address(t2), amount); @@ -103,18 +99,13 @@ contract EulerSwapTest is MaglevTestBase { cx = bound(cx, 0.01e18, 0.99e18); cy = bound(cy, 0.01e18, 0.99e18); - uint px = price; - uint py = 1e18; + uint256 px = price; + uint256 py = 1e18; oracle.setPrice(address(eTST), unitOfAccount, price); oracle.setPrice(address(assetTST), unitOfAccount, price); vm.prank(owner); - maglev.setEulerSwapParams(Maglev.EulerSwapParams({ - px: px, - py: py, - cx: cx, - cy: cy - })); + maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: cx, cy: cy})); int256 origNAV = getHolderNAV(); diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index 7db8146..cd28a4f 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -64,10 +64,12 @@ contract MaglevTestBase is EVaultTestBase { 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); + 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 int(balValue) - int(debtValue); + return int256(balValue) - int256(debtValue); } modifier monotonicHolderNAV() { From ee98e21cafe3dd664e3adddb5dddda5a83ad7edd Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sun, 8 Dec 2024 21:04:11 -0500 Subject: [PATCH 036/312] oz sqrt --- src/MaglevEulerSwap.sol | 47 ++--------------------------------------- 1 file changed, 2 insertions(+), 45 deletions(-) diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index bd9d95c..16ff31b 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; import {console} from "forge-std/Test.sol"; +import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {MaglevBase} from "./MaglevBase.sol"; contract MaglevEulerSwap is MaglevBase { @@ -109,7 +110,7 @@ contract MaglevEulerSwap is MaglevBase { + int256(y0) * (1e18 - 2 * int256(cy)) / 1e18; int256 c = (int256(cy) - 1e18) * int256(y0) ** 2 / 1e18 / 1e18; uint256 discriminant = uint256(int256(uint256(b ** 2)) - 4 * int256(a) * int256(c)); - uint256 numerator = uint256(-b + int256(uint256(sqrt(discriminant)))); + uint256 numerator = uint256(-b + int256(uint256(Math.sqrt(discriminant)))); uint256 denominator = 2 * a; return numerator * 1e18 / denominator; } @@ -172,48 +173,4 @@ contract MaglevEulerSwap is MaglevBase { // if distance is > zero, then point is above the curve, and invariant passes return (delta >= 0); } - - // EIP-7054 - function sqrt(uint256 x) internal pure returns (uint128) { - if (x == 0) { - return 0; - } else { - uint256 xx = x; - uint256 r = 1; - if (xx >= 0x100000000000000000000000000000000) { - xx >>= 128; - r <<= 64; - } - if (xx >= 0x10000000000000000) { - xx >>= 64; - r <<= 32; - } - if (xx >= 0x100000000) { - xx >>= 32; - r <<= 16; - } - if (xx >= 0x10000) { - xx >>= 16; - r <<= 8; - } - if (xx >= 0x100) { - xx >>= 8; - r <<= 4; - } - if (xx >= 0x10) { - xx >>= 4; - r <<= 2; - } - if (xx >= 0x8) r <<= 1; - r = (r + x / r) >> 1; - r = (r + x / r) >> 1; - r = (r + x / r) >> 1; - r = (r + x / r) >> 1; - r = (r + x / r) >> 1; - r = (r + x / r) >> 1; - r = (r + x / r) >> 1; - uint256 r1 = x / r; - return uint128(r < r1 ? r : r1); - } - } } From 8d10376fa98ca4d3c5228476025ed1d08783982b Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sun, 8 Dec 2024 21:08:41 -0500 Subject: [PATCH 037/312] refactor --- src/MaglevEulerSwap.sol | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index 16ff31b..d387efd 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -32,9 +32,16 @@ contract MaglevEulerSwap is MaglevBase { } function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) internal view virtual override { - require( - verifyCurve(newReserve0, newReserve1, _px, _py, initialReserve0, initialReserve1, _cx, _cy), KNotSatisfied() - ); + int256 delta = 0; + + if (newReserve0 >= initialReserve0) { + delta = int256(newReserve0) - int256(fy(newReserve1, _px, _py, initialReserve0, initialReserve1, _cx, _cy)); + } else { + delta = int256(newReserve1) - int256(fx(newReserve0, _px, _py, initialReserve0, initialReserve1, _cx, _cy)); + } + + // if delta is > zero, then point is above the curve + require(delta >= 0 , KNotSatisfied()); } uint256 private constant roundingCompensation = 1.0000000000001e18; @@ -156,21 +163,4 @@ contract MaglevEulerSwap is MaglevBase { return (dx, dy); } - - function verifyCurve(uint256 xt, uint256 yt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) - internal - pure - returns (bool) - { - int256 delta = 0; - - if (xt >= x0) { - delta = int256(xt) - int256(fy(yt, px, py, x0, y0, cx, cy)); - } else { - delta = int256(yt) - int256(fx(xt, px, py, x0, y0, cx, cy)); - } - - // if distance is > zero, then point is above the curve, and invariant passes - return (delta >= 0); - } } From 3a50c37822ee76c19a456f1f595054b256a6aba8 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sun, 8 Dec 2024 23:36:55 -0500 Subject: [PATCH 038/312] cleanup --- src/MaglevEulerSwap.sol | 86 +++++++++++++++++------------------------ test/EulerSwap.t.sol | 16 +++++++- 2 files changed, 50 insertions(+), 52 deletions(-) diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index d387efd..ac81f99 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -12,6 +12,8 @@ contract MaglevEulerSwap is MaglevBase { uint256 public _cy; error KNotSatisfied(); + error ReservesZero(); + error InvalidInputCoordinate(); struct EulerSwapParams { uint256 px; @@ -51,7 +53,7 @@ contract MaglevEulerSwap is MaglevBase { view virtual override - returns (uint256) + returns (uint256 output) { int256 dx; int256 dy; @@ -64,9 +66,22 @@ contract MaglevEulerSwap is MaglevBase { else dx = -int256(amount); } - (dx, dy) = simulateSwap(dx, dy, reserve0, reserve1, _px, _py, initialReserve0, initialReserve1, _cx, _cy); - - uint256 output; + { + int256 reserve0New = int256(uint256(reserve0)); + int256 reserve1New = int256(uint256(reserve1)); + + if (dx != 0) { + reserve0New += dx; + reserve1New = int256(fx(uint256(reserve0New), _px, _py, initialReserve0, initialReserve1, _cx, _cy)); + } + if (dy != 0) { + reserve1New += dy; + reserve0New = int256(fy(uint256(reserve1New), _px, _py, initialReserve0, initialReserve1, _cx, _cy)); + } + + dx = reserve0New - int256(uint256(reserve0)); + dy = reserve1New - int256(uint256(reserve1)); + } if (exactIn) { if (asset0IsInput) output = uint256(-dy); @@ -77,8 +92,6 @@ contract MaglevEulerSwap is MaglevBase { else output = uint256(dy); output = output * roundingCompensation / 1e18; } - - return output; } ///// @@ -88,7 +101,7 @@ contract MaglevEulerSwap is MaglevBase { pure returns (uint256) { - require(xt > 0, "Reserves must be greater than zero"); + require(xt > 0, ReservesZero()); if (xt <= x0) { return fx1(xt, px, py, x0, y0, cx, cy); } else { @@ -96,12 +109,25 @@ contract MaglevEulerSwap is MaglevBase { } } + function fy(uint256 yt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) + internal + pure + returns (uint256) + { + require(yt > 0, ReservesZero()); + if (yt <= y0) { + return fx1(yt, py, px, y0, x0, cy, cx); + } else { + return fx2(yt, py, px, y0, x0, cy, cx); + } + } + function fx1(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256) internal pure returns (uint256) { - require(xt <= x0, "Invalid input coordinate"); + require(xt <= x0, InvalidInputCoordinate()); return y0 + px * 1e18 / py * (cx * (2 * x0 - xt) / 1e18 + (1e18 - cx) * x0 / 1e18 * x0 / xt - x0) / 1e18; } @@ -110,7 +136,7 @@ contract MaglevEulerSwap is MaglevBase { pure returns (uint256) { - require(xt > x0, "Invalid input coordinate"); + require(xt > x0, InvalidInputCoordinate()); // intermediate values for solving quadratic equation uint256 a = cy; int256 b = (int256(px) * 1e18 / int256(py)) * (int256(xt) - int256(x0)) / 1e18 @@ -121,46 +147,4 @@ contract MaglevEulerSwap is MaglevBase { uint256 denominator = 2 * a; return numerator * 1e18 / denominator; } - - function fy(uint256 yt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) - internal - pure - returns (uint256) - { - require(yt > 0, "Reserves must be greater than zero"); - if (yt <= y0) { - return fx1(yt, py, px, y0, x0, cy, cx); - } else { - return fx2(yt, py, px, y0, x0, cy, cx); - } - } - - function simulateSwap( - int256 dx, - int256 dy, - uint256 xt, - uint256 yt, - uint256 px, - uint256 py, - uint256 x0, - uint256 y0, - uint256 cx, - uint256 cy - ) internal pure returns (int256, int256) { - int256 xtNew = int256(xt); - int256 ytNew = int256(yt); - - if (dx != 0) { - xtNew += dx; - ytNew = int256(fx(uint256(xtNew), px, py, x0, y0, cx, cy)); - } - if (dy != 0) { - ytNew += dy; - xtNew = int256(fy(uint256(ytNew), px, py, x0, y0, cx, cy)); - } - dx = xtNew - int256(xt); - dy = ytNew - int256(yt); - - return (dx, dy); - } } diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 8aa07cd..97ec71b 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -30,9 +30,23 @@ contract EulerSwapTest is MaglevTestBase { maglev.setDebtLimit(50e18, 50e18); } - function test_basicSwap() public monotonicHolderNAV { + function test_basicSwap_exactIn() public monotonicHolderNAV { uint256 amountIn = 1e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); + assertApproxEqAbs(amountOut, 0.9974e18, 0.0001e18); + + assetTST.mint(address(this), amountIn); + + assetTST.transfer(address(maglev), amountIn); + maglev.swap(0, amountOut, address(this), ""); + + assertEq(assetTST2.balanceOf(address(this)), amountOut); + } + + function test_basicSwap_exactOut() public monotonicHolderNAV { + uint256 amountOut = 1e18; + uint256 amountIn = maglev.quoteExactOutput(address(assetTST), address(assetTST2), amountOut); + assertApproxEqAbs(amountIn, 1.0025e18, 0.0001e18); assetTST.mint(address(this), amountIn); From b75c9474091b37ebd55df0bb65db17054a67b28b Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sun, 8 Dec 2024 23:38:39 -0500 Subject: [PATCH 039/312] cleanup --- src/MaglevEulerSwap.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index ac81f99..a9b65c8 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -43,7 +43,7 @@ contract MaglevEulerSwap is MaglevBase { } // if delta is > zero, then point is above the curve - require(delta >= 0 , KNotSatisfied()); + require(delta >= 0, KNotSatisfied()); } uint256 private constant roundingCompensation = 1.0000000000001e18; @@ -94,7 +94,7 @@ contract MaglevEulerSwap is MaglevBase { } } - ///// + ///// Curve math routines function fx(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) internal From ba0da9b71f6fa2004b1ebbcaba254214c924bfcf Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 9 Dec 2024 00:14:10 -0500 Subject: [PATCH 040/312] start of fee support for ES curve --- TODO | 1 + src/MaglevEulerSwap.sol | 12 +++++++----- test/EulerSwap.t.sol | 6 +++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index 3f3156c..7efd701 100644 --- a/TODO +++ b/TODO @@ -2,6 +2,7 @@ * events * reserve change on each swap * ConstantSum: incorporate price multipliers in quote methods +* natspec ? alternate curves ? registry contract ? transparent proxy so AMM address can stay constant diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index a9b65c8..ea06415 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -10,6 +10,7 @@ contract MaglevEulerSwap is MaglevBase { uint256 public _py; uint256 public _cx; uint256 public _cy; + uint256 public _fee; error KNotSatisfied(); error ReservesZero(); @@ -20,6 +21,7 @@ contract MaglevEulerSwap is MaglevBase { uint256 py; uint256 cx; uint256 cy; + uint256 fee; } constructor(BaseParams memory baseParams, EulerSwapParams memory params) MaglevBase(baseParams) { @@ -31,8 +33,10 @@ contract MaglevEulerSwap is MaglevBase { _py = params.py; _cx = params.cx; _cy = params.cy; + _fee = Math.max(params.fee, 1.0000000000001e18); // minimum fee required to compensate for rounding } + // FIXME: how to charge fees? function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) internal view virtual override { int256 delta = 0; @@ -42,12 +46,10 @@ contract MaglevEulerSwap is MaglevBase { delta = int256(newReserve1) - int256(fx(newReserve0, _px, _py, initialReserve0, initialReserve1, _cx, _cy)); } - // if delta is > zero, then point is above the curve + // if delta is >= zero, then point is on or above the curve require(delta >= 0, KNotSatisfied()); } - uint256 private constant roundingCompensation = 1.0000000000001e18; - function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view @@ -86,11 +88,11 @@ contract MaglevEulerSwap is MaglevBase { if (exactIn) { if (asset0IsInput) output = uint256(-dy); else output = uint256(-dx); - output = output * 1e18 / roundingCompensation; + output = output * 1e18 / _fee; } else { if (asset0IsInput) output = uint256(dx); else output = uint256(dy); - output = output * roundingCompensation / 1e18; + output = output * _fee / 1e18; } } diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 97ec71b..d4efd3a 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -18,7 +18,7 @@ contract EulerSwapTest is MaglevTestBase { vm.prank(owner); maglev = - new Maglev(_getMaglevBaseParams(), Maglev.EulerSwapParams({px: 1e18, py: 1e18, cx: 0.4e18, cy: 0.85e18})); + new Maglev(_getMaglevBaseParams(), Maglev.EulerSwapParams({px: 1e18, py: 1e18, cx: 0.4e18, cy: 0.85e18, fee:0})); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); @@ -66,7 +66,7 @@ contract EulerSwapTest is MaglevTestBase { int256 origNAV = getHolderNAV(); vm.prank(owner); - maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: 0.4e18, cy: 0.85e18})); + maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: 0.4e18, cy: 0.85e18, fee:0})); uint256 amountIn = 1e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); @@ -119,7 +119,7 @@ contract EulerSwapTest is MaglevTestBase { oracle.setPrice(address(assetTST), unitOfAccount, price); vm.prank(owner); - maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: cx, cy: cy})); + maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: cx, cy: cy, fee:0})); int256 origNAV = getHolderNAV(); From 5977df1140504ea727832b28f48d673825e22614 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 9 Dec 2024 00:23:50 -0500 Subject: [PATCH 041/312] todo --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index 7efd701..465f6ad 100644 --- a/TODO +++ b/TODO @@ -3,6 +3,9 @@ * reserve change on each swap * ConstantSum: incorporate price multipliers in quote methods * natspec +? onlyEVCAccountOwner +? should uniswapV2Call take _msgSender instead of msg.sender? + - I think no, since swap isn't intended to be EVC-compatible ? alternate curves ? registry contract ? transparent proxy so AMM address can stay constant From ba58bbfd335283e5dd1a501afa29bc5eb32efe02 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 9 Dec 2024 00:25:10 -0500 Subject: [PATCH 042/312] fmt --- test/EulerSwap.t.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index d4efd3a..0740f27 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -17,8 +17,9 @@ contract EulerSwapTest is MaglevTestBase { super.setUp(); vm.prank(owner); - maglev = - new Maglev(_getMaglevBaseParams(), Maglev.EulerSwapParams({px: 1e18, py: 1e18, cx: 0.4e18, cy: 0.85e18, fee:0})); + maglev = new Maglev( + _getMaglevBaseParams(), Maglev.EulerSwapParams({px: 1e18, py: 1e18, cx: 0.4e18, cy: 0.85e18, fee: 0}) + ); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); @@ -66,7 +67,7 @@ contract EulerSwapTest is MaglevTestBase { int256 origNAV = getHolderNAV(); vm.prank(owner); - maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: 0.4e18, cy: 0.85e18, fee:0})); + maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: 0.4e18, cy: 0.85e18, fee: 0})); uint256 amountIn = 1e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); @@ -119,7 +120,7 @@ contract EulerSwapTest is MaglevTestBase { oracle.setPrice(address(assetTST), unitOfAccount, price); vm.prank(owner); - maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: cx, cy: cy, fee:0})); + maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: cx, cy: cy, fee: 0})); int256 origNAV = getHolderNAV(); From 0a8a523f1c7b44beb2bfe12d8ece4aa41fd3d1b2 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 9 Dec 2024 11:47:59 -0500 Subject: [PATCH 043/312] depends on solc 0.8.27 due to custom errors in require() --- foundry.toml | 1 + src/MaglevBase.sol | 2 +- src/MaglevConstantProduct.sol | 2 +- src/MaglevConstantSum.sol | 2 +- src/MaglevEulerSwap.sol | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/foundry.toml b/foundry.toml index 25b918f..fc855a1 100644 --- a/foundry.toml +++ b/foundry.toml @@ -2,5 +2,6 @@ src = "src" out = "out" libs = ["lib"] +solc = "0.8.27" # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 8c727e9..114a178 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; +pragma solidity ^0.8.27; import {console} from "forge-std/Test.sol"; import {Ownable, Context} from "openzeppelin-contracts/access/Ownable.sol"; diff --git a/src/MaglevConstantProduct.sol b/src/MaglevConstantProduct.sol index 62f8a01..968d284 100644 --- a/src/MaglevConstantProduct.sol +++ b/src/MaglevConstantProduct.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; +pragma solidity ^0.8.27; import {MaglevBase} from "./MaglevBase.sol"; diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index 5c03d32..3ebc5f9 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; +pragma solidity ^0.8.27; import {MaglevBase} from "./MaglevBase.sol"; diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index ea06415..b2204ec 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; +pragma solidity ^0.8.27; import {console} from "forge-std/Test.sol"; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; From 5893e3f86624c9bc6219739e910ad3da6766936a Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 9 Dec 2024 12:13:47 -0500 Subject: [PATCH 044/312] todo --- TODO | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO b/TODO index 465f6ad..529b23b 100644 --- a/TODO +++ b/TODO @@ -3,6 +3,7 @@ * reserve change on each swap * ConstantSum: incorporate price multipliers in quote methods * natspec +* permit2 instead of regular approval: measure gas savings ? onlyEVCAccountOwner ? should uniswapV2Call take _msgSender instead of msg.sender? - I think no, since swap isn't intended to be EVC-compatible From 8e6fc4f0fd4f8a6a575d18fd29b9d94411349cf0 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 11 Dec 2024 01:38:35 -0500 Subject: [PATCH 045/312] rounding test case --- src/MaglevEulerSwap.sol | 3 ++- test/EulerSwap.t.sol | 23 ++++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index b2204ec..b10c15c 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -33,7 +33,8 @@ contract MaglevEulerSwap is MaglevBase { _py = params.py; _cx = params.cx; _cy = params.cy; - _fee = Math.max(params.fee, 1.0000000000001e18); // minimum fee required to compensate for rounding + _fee = 1e18 + params.fee; + //_fee = Math.max(1e18 + params.fee, 1.0000000000001e18); // minimum fee required to compensate for rounding } // FIXME: how to charge fees? diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 0740f27..70a837c 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -13,12 +13,14 @@ import {MaglevEulerSwap as Maglev} from "../src/MaglevEulerSwap.sol"; contract EulerSwapTest is MaglevTestBase { Maglev public maglev; + uint256 minFee = 0.0000000000001e18; + function setUp() public virtual override { super.setUp(); vm.prank(owner); maglev = new Maglev( - _getMaglevBaseParams(), Maglev.EulerSwapParams({px: 1e18, py: 1e18, cx: 0.4e18, cy: 0.85e18, fee: 0}) + _getMaglevBaseParams(), Maglev.EulerSwapParams({px: 1e18, py: 1e18, cx: 0.4e18, cy: 0.85e18, fee: minFee}) ); vm.prank(holder); @@ -67,7 +69,7 @@ contract EulerSwapTest is MaglevTestBase { int256 origNAV = getHolderNAV(); vm.prank(owner); - maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: 0.4e18, cy: 0.85e18, fee: 0})); + maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: 0.4e18, cy: 0.85e18, fee: minFee})); uint256 amountIn = 1e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); @@ -120,7 +122,7 @@ contract EulerSwapTest is MaglevTestBase { oracle.setPrice(address(assetTST), unitOfAccount, price); vm.prank(owner); - maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: cx, cy: cy, fee: 0})); + maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: cx, cy: cy, fee: minFee})); int256 origNAV = getHolderNAV(); @@ -147,4 +149,19 @@ contract EulerSwapTest is MaglevTestBase { assertGe(getHolderNAV(), origNAV); } + + function test_roundingFailure() public { + vm.skip(true); + + vm.prank(owner); + maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: 1e18, py: 1e18, cx: 0.4e18, cy: 0.85e18, fee: 0})); + + uint256 amountIn = 1.4e18; + uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); + + assetTST.mint(address(this), amountIn); + assetTST.transfer(address(maglev), amountIn); + maglev.swap(0, amountOut, address(this), ""); + assertEq(assetTST2.balanceOf(address(this)), amountOut); + } } From 6aafe89d84a4dbb51b71ad9637e5e22b0c034c1b Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 13 Dec 2024 09:34:29 -0500 Subject: [PATCH 046/312] store fees without 1e18 offset --- src/MaglevEulerSwap.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index b10c15c..0aa8667 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -33,8 +33,8 @@ contract MaglevEulerSwap is MaglevBase { _py = params.py; _cx = params.cx; _cy = params.cy; - _fee = 1e18 + params.fee; - //_fee = Math.max(1e18 + params.fee, 1.0000000000001e18); // minimum fee required to compensate for rounding + _fee = params.fee; + //_fee = Math.max(params.fee, 0.0000000000001e18); // minimum fee required to compensate for rounding } // FIXME: how to charge fees? @@ -89,11 +89,11 @@ contract MaglevEulerSwap is MaglevBase { if (exactIn) { if (asset0IsInput) output = uint256(-dy); else output = uint256(-dx); - output = output * 1e18 / _fee; + output = output * 1e18 / (1e18 + _fee); } else { if (asset0IsInput) output = uint256(dx); else output = uint256(dy); - output = output * _fee / 1e18; + output = output * (1e18 + _fee) / 1e18; } } From 5e450bd6b38184c3184e57a9800f6c0331d72bf6 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 13 Dec 2024 12:30:32 -0500 Subject: [PATCH 047/312] verify doesn't have to be a view --- src/MaglevBase.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 114a178..6fff167 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -196,7 +196,6 @@ abstract contract MaglevBase is EVCUtil, Ownable { function verify(uint256 amount0In, uint256 amount1In, uint256 newReserve0, uint256 newReserve1) internal - view virtual; function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view virtual returns (uint256); From 4b74e007cdbad06be206636a67065c3e37d01647 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 13 Dec 2024 18:59:18 -0500 Subject: [PATCH 048/312] move fee logic to base class so it's shared by all curves --- src/MaglevBase.sol | 36 +++++++++++++++++++++------ src/MaglevConstantProduct.sol | 21 ++++------------ src/MaglevConstantSum.sol | 27 ++++++-------------- src/MaglevEulerSwap.sol | 10 +++----- test/ConstantProduct.t.sol | 37 +++++++++++++++++++++------ test/ConstantSum.t.sol | 47 +++++++++++++++++------------------ test/EulerSwap.t.sol | 26 +++++++------------ test/MaglevTestBase.t.sol | 4 +-- 8 files changed, 108 insertions(+), 100 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 6fff167..778bbd8 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -14,6 +14,9 @@ abstract contract MaglevBase is EVCUtil, Ownable { address public immutable asset0; address public immutable asset1; address public immutable myAccount; + uint112 public immutable debtLimit0; + uint112 public immutable debtLimit1; + uint256 public immutable feeMultiplier; uint112 public reserve0; uint112 public reserve1; @@ -25,6 +28,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { error Reentrancy(); error Overflow(); error UnsupportedPair(); + error BadFee(); error InsufficientReserves(); error InsufficientCash(); @@ -44,14 +48,22 @@ abstract contract MaglevBase is EVCUtil, Ownable { address vault0; address vault1; address myAccount; + uint112 debtLimit0; + uint112 debtLimit1; + uint256 fee; } constructor(BaseParams memory params) EVCUtil(params.evc) Ownable(msg.sender) { + require(params.fee < 1e18, BadFee()); + vault0 = params.vault0; vault1 = params.vault1; asset0 = IEVault(vault0).asset(); asset1 = IEVault(vault1).asset(); myAccount = params.myAccount; + reserve0 = initialReserve0 = adjustReserve(params.debtLimit0, vault0); + reserve1 = initialReserve1 = adjustReserve(params.debtLimit1, vault1); + feeMultiplier = 1e18 - params.fee; } // Owner functions @@ -65,11 +77,6 @@ abstract contract MaglevBase is EVCUtil, Ownable { IEVC(evc).enableCollateral(myAccount, vault1); } - function setDebtLimit(uint112 debtLimit0, uint112 debtLimit1) external onlyOwner { - reserve0 = initialReserve0 = adjustReserve(debtLimit0, vault0); - reserve1 = initialReserve1 = adjustReserve(debtLimit1, vault1); - } - // Swapper interface function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) @@ -86,12 +93,19 @@ abstract contract MaglevBase is EVCUtil, Ownable { if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data); - // Deposit all available funds + // Deposit all available funds, adjust received amounts downward to collect fees uint256 amount0In = IERC20(asset0).balanceOf(address(this)); + if (amount0In > 0) { + depositAssets(vault0, amount0In); + amount0In = amount0In * feeMultiplier / 1e18; + } + uint256 amount1In = IERC20(asset1).balanceOf(address(this)); - if (amount0In > 0) depositAssets(vault0, amount0In); - if (amount1In > 0) depositAssets(vault1, amount1In); + if (amount1In > 0) { + depositAssets(vault1, amount1In); + amount1In = amount1In * feeMultiplier / 1e18; + } // Verify curve invariant is satisified @@ -176,6 +190,9 @@ abstract contract MaglevBase is EVCUtil, Ownable { view returns (uint256) { + // exactIn: decrease received amountIn, rounding down + if (exactIn) amount = amount * feeMultiplier / 1e18; + bool asset0IsInput; if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true; else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; @@ -189,6 +206,9 @@ abstract contract MaglevBase is EVCUtil, Ownable { InsufficientCash() ); + // exactOut: increase required amountIn, rounding up + if (!exactIn) quote = (quote * 1e18 + (feeMultiplier - 1)) / feeMultiplier; + return quote; } diff --git a/src/MaglevConstantProduct.sol b/src/MaglevConstantProduct.sol index 968d284..996359a 100644 --- a/src/MaglevConstantProduct.sol +++ b/src/MaglevConstantProduct.sol @@ -4,34 +4,23 @@ pragma solidity ^0.8.27; import {MaglevBase} from "./MaglevBase.sol"; contract MaglevConstantProduct is MaglevBase { - uint64 public fee; - error KNotSatisfied(); - struct ConstantProductParams { - uint64 fee; - } - - constructor(BaseParams memory baseParams, ConstantProductParams memory params) MaglevBase(baseParams) { - setConstantProductParams(params); - } - - function setConstantProductParams(ConstantProductParams memory params) public onlyOwner { - fee = params.fee; + constructor(BaseParams memory baseParams) MaglevBase(baseParams) { } function k(uint256 r0, uint256 r1) public pure returns (uint256) { return r0 * r1; } - function verify(uint256 amount0In, uint256 amount1In, uint256 newReserve0, uint256 newReserve1) + function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) internal view virtual override { uint256 kBefore = k(reserve0, reserve1); - uint256 kAfter = k(newReserve0 - (amount0In * fee / 1e18), newReserve1 - (amount1In * fee / 1e18)); + uint256 kAfter = k(newReserve0, newReserve1); require(kAfter >= kBefore, KNotSatisfied()); } @@ -46,9 +35,9 @@ contract MaglevConstantProduct is MaglevBase { uint256 reserveOut = asset0IsInput ? reserve1 : reserve0; if (exactIn) { - return (reserveOut * amount) / (reserveIn + amount) * (1e18 - fee) / 1e18; + return (reserveOut * amount) / (reserveIn + amount); } else { - return (reserveIn * amount) / (reserveOut - amount) * 1e18 / (1e18 - fee); + return (reserveIn * amount) / (reserveOut - amount); } } } diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index 3ebc5f9..9f9cfd9 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -4,24 +4,17 @@ pragma solidity ^0.8.27; import {MaglevBase} from "./MaglevBase.sol"; contract MaglevConstantSum is MaglevBase { - uint64 public fee; - uint96 public priceA; - uint96 public priceB; + uint256 public immutable priceA; + uint256 public immutable priceB; error KNotSatisfied(); struct ConstantSumParams { - uint64 fee; - uint96 priceA; - uint96 priceB; + uint256 priceA; + uint256 priceB; } constructor(BaseParams memory baseParams, ConstantSumParams memory params) MaglevBase(baseParams) { - setConstantSumParams(params); - } - - function setConstantSumParams(ConstantSumParams memory params) public onlyOwner { - fee = params.fee; priceA = params.priceA; priceB = params.priceB; } @@ -30,24 +23,20 @@ contract MaglevConstantSum is MaglevBase { return (r0 * priceA) + (r1 * priceB); } - function verify(uint256 amount0In, uint256 amount1In, uint256 newReserve0, uint256 newReserve1) + function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) internal view virtual override { uint256 kBefore = k(reserve0, reserve1); - uint256 kAfter = k(newReserve0 - (amount0In * fee / 1e18), newReserve1 - (amount1In * fee / 1e18)); + uint256 kAfter = k(newReserve0, newReserve1); require(kAfter >= kBefore, KNotSatisfied()); } // FIXME: incorporate priceA and priceB - function computeQuote(uint256 amount, bool exactIn, bool) internal view virtual override returns (uint256) { - if (exactIn) { - return amount * (1e18 - fee) / 1e18; - } else { - return amount * 1e18 / (1e18 - fee); - } + function computeQuote(uint256 amount, bool, bool) internal view virtual override returns (uint256) { + return amount; } } diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index 0aa8667..49fdad2 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -10,7 +10,6 @@ contract MaglevEulerSwap is MaglevBase { uint256 public _py; uint256 public _cx; uint256 public _cy; - uint256 public _fee; error KNotSatisfied(); error ReservesZero(); @@ -21,7 +20,6 @@ contract MaglevEulerSwap is MaglevBase { uint256 py; uint256 cx; uint256 cy; - uint256 fee; } constructor(BaseParams memory baseParams, EulerSwapParams memory params) MaglevBase(baseParams) { @@ -33,8 +31,6 @@ contract MaglevEulerSwap is MaglevBase { _py = params.py; _cx = params.cx; _cy = params.cy; - _fee = params.fee; - //_fee = Math.max(params.fee, 0.0000000000001e18); // minimum fee required to compensate for rounding } // FIXME: how to charge fees? @@ -51,6 +47,8 @@ contract MaglevEulerSwap is MaglevBase { require(delta >= 0, KNotSatisfied()); } + uint256 private constant roundingCompensation = 1.0000000000001e18; + function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view @@ -89,11 +87,11 @@ contract MaglevEulerSwap is MaglevBase { if (exactIn) { if (asset0IsInput) output = uint256(-dy); else output = uint256(-dx); - output = output * 1e18 / (1e18 + _fee); + output = output * 1e18 / roundingCompensation; } else { if (asset0IsInput) output = uint256(dx); else output = uint256(dy); - output = output * (1e18 + _fee) / 1e18; + output = output * roundingCompensation / 1e18; } } diff --git a/test/ConstantProduct.t.sol b/test/ConstantProduct.t.sol index f93e60f..2e13d97 100644 --- a/test/ConstantProduct.t.sol +++ b/test/ConstantProduct.t.sol @@ -16,17 +16,34 @@ contract ConstantProductTest is MaglevTestBase { function setUp() public virtual override { super.setUp(); + createMaglev(50e18, 50e18, 0); + } + + function createMaglev(uint112 debtLimit0, uint112 debtLimit1, uint256 fee) internal { vm.prank(owner); - maglev = new Maglev(_getMaglevBaseParams(), Maglev.ConstantProductParams({fee: 0})); + maglev = new Maglev(getMaglevBaseParams(debtLimit0, debtLimit1, fee)); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); vm.prank(owner); maglev.configure(); + } - vm.prank(owner); - maglev.setDebtLimit(50e18, 50e18); + function test_basicExactIn() public monotonicHolderNAV { + uint256 amount = 1e18; + + assetTST.mint(address(this), amount); + + uint256 q = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount); + + assetTST.transfer(address(maglev), amount); + + vm.expectRevert(Maglev.KNotSatisfied.selector); + maglev.swap(0, q+1, address(this), ""); + + maglev.swap(0, q, address(this), ""); + assertEq(assetTST2.balanceOf(address(this)), q); } function test_fee_exactIn(uint256 amount, bool dir) public monotonicHolderNAV { @@ -39,15 +56,20 @@ contract ConstantProductTest is MaglevTestBase { t1.mint(address(this), amount); - uint256 qOrig = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount); + uint256 qOrig = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount * 0.998e18 / 1e18); - vm.prank(owner); - maglev.setConstantProductParams(Maglev.ConstantProductParams({fee: 0.002e18})); + createMaglev(50e18, 50e18, 0.002e18); uint256 q = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount); - assertApproxEqAbs(1e18 * q / qOrig, 0.998e18, 0.000000000001e18); + + assertEq(qOrig, q); t1.transfer(address(maglev), amount); + + vm.expectRevert(Maglev.KNotSatisfied.selector); + if (dir) maglev.swap(0, q+1, address(this), ""); + else maglev.swap(q+1, 0, address(this), ""); + if (dir) maglev.swap(0, q, address(this), ""); else maglev.swap(q, 0, address(this), ""); assertEq(t2.balanceOf(address(this)), q); @@ -72,7 +94,6 @@ contract ConstantProductTest is MaglevTestBase { t2.transfer(address(maglev), q); if (dir) maglev.swap(amount - 2, 0, address(this), ""); // - 2 due to rounding - else maglev.swap(0, amount - 2, address(this), ""); uint256 q2 = maglev.quoteExactInput(address(t1), address(t2), amount); diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index d9609ab..2e5d4bc 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -16,17 +16,18 @@ contract ConstantSumTest is MaglevTestBase { function setUp() public virtual override { super.setUp(); + createMaglev(50e18, 50e18, 0, 1, 1); + } + + function createMaglev(uint112 debtLimit0, uint112 debtLimit1, uint256 fee, uint256 priceA, uint256 priceB) internal { vm.prank(owner); - maglev = new Maglev(_getMaglevBaseParams(), Maglev.ConstantSumParams({fee: 0, priceA: 1, priceB: 1})); + maglev = new Maglev(getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.ConstantSumParams({priceA: priceA, priceB: priceB})); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); vm.prank(owner); maglev.configure(); - - vm.prank(owner); - maglev.setDebtLimit(50e18, 50e18); } function test_basicSwapReport() public monotonicHolderNAV { @@ -65,7 +66,7 @@ contract ConstantSumTest is MaglevTestBase { { uint256 amount = 60.000001e18; assetTST.transfer(address(maglev), amount); - vm.expectRevert(); // FIXME: which error? + vm.expectRevert(); // FIXME: currently an arithmetic underflow. should make this a proper error maglev.swap(0, amount, address(this), ""); } @@ -84,29 +85,28 @@ contract ConstantSumTest is MaglevTestBase { // Same debt limit means reserves not affected - vm.prank(owner); - maglev.setDebtLimit(50e18, 50e18); + createMaglev(50e18, 50e18, 0, 1, 1); + assertEq(maglev.reserve0(), 120e18); assertEq(maglev.reserve1(), 0e18); // Increase debt limit on one side - vm.prank(owner); - maglev.setDebtLimit(50e18, 55e18); + createMaglev(50e18, 55e18, 0, 1, 1); + assertEq(maglev.reserve0(), 120e18); assertEq(maglev.reserve1(), 5e18); // And the other - vm.prank(owner); - maglev.setDebtLimit(55e18, 55e18); + createMaglev(55e18, 55e18, 0, 1, 1); + assertEq(maglev.reserve0(), 125e18); assertEq(maglev.reserve1(), 5e18); // Shrink debt limit - vm.prank(owner); - maglev.setDebtLimit(40e18, 45e18); + createMaglev(40e18, 45e18, 0, 1, 1); assertEq(maglev.reserve0(), 110e18); assertEq(maglev.reserve1(), 0e18); // can't go below 0 @@ -130,12 +130,12 @@ contract ConstantSumTest is MaglevTestBase { } function test_quoteExactInput() public monotonicHolderNAV { - vm.prank(owner); - maglev.setConstantSumParams(Maglev.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); + createMaglev(50e18, 50e18, 0.003e18, 1, 1); assetTST.mint(address(this), 100e18); + uint256 q = maglev.quoteExactInput(address(assetTST), address(assetTST2), 1e18); - assertLt(q, 1e18); + assertEq(q, 0.997e18); assetTST.transfer(address(maglev), 1e18); maglev.swap(0, q, recipient, ""); @@ -143,13 +143,12 @@ contract ConstantSumTest is MaglevTestBase { } function test_quoteExactOutput() public monotonicHolderNAV { - vm.prank(owner); - maglev.setConstantSumParams(Maglev.ConstantSumParams({fee: 0.003e18, priceA: 1, priceB: 1})); + createMaglev(50e18, 50e18, 0.003e18, 1, 1); assetTST.mint(address(this), 100e18); uint256 q = maglev.quoteExactOutput(address(assetTST), address(assetTST2), 1e18); - assertGt(q, 1e18); + assertEq(q, 1.003009027081243732e18); assetTST.transfer(address(maglev), q); maglev.swap(0, 1e18, recipient, ""); @@ -160,13 +159,13 @@ contract ConstantSumTest is MaglevTestBase { fee = bound(fee, 0, 0.02e18); amount1 = bound(amount1, 1e18, 25e18); - vm.prank(owner); - maglev.setConstantSumParams(Maglev.ConstantSumParams({fee: uint64(fee), priceA: 1, priceB: 1})); + createMaglev(50e18, 50e18, fee, 1, 1); assetTST.mint(address(this), 100e18); assetTST2.mint(address(this), 100e18); - uint256 needed = amount1 * 1e18 / (1e18 - fee); + uint256 feeMultiplier = 1e18 - fee; + uint256 needed = (amount1 * 1e18 + (feeMultiplier - 1)) / feeMultiplier; console.log(amount1, needed, fee); TestERC20 tt; @@ -186,12 +185,12 @@ contract ConstantSumTest is MaglevTestBase { a2 = 0; } - tt.transfer(address(maglev), needed - 2); + tt.transfer(address(maglev), needed - 1); vm.expectRevert(Maglev.KNotSatisfied.selector); maglev.swap(a1, a2, recipient, ""); - tt.transfer(address(maglev), 2); + tt.transfer(address(maglev), 1); maglev.swap(a1, a2, recipient, ""); assertEq(tt2.balanceOf(recipient), amount1); diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 70a837c..caaf3aa 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -13,26 +13,24 @@ import {MaglevEulerSwap as Maglev} from "../src/MaglevEulerSwap.sol"; contract EulerSwapTest is MaglevTestBase { Maglev public maglev; - uint256 minFee = 0.0000000000001e18; - function setUp() public virtual override { super.setUp(); + createMaglev(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + } + + function createMaglev(uint112 debtLimit0, uint112 debtLimit1, uint256 fee, uint256 px, uint256 py, uint256 cx, uint256 cy) internal { vm.prank(owner); - maglev = new Maglev( - _getMaglevBaseParams(), Maglev.EulerSwapParams({px: 1e18, py: 1e18, cx: 0.4e18, cy: 0.85e18, fee: minFee}) - ); + maglev = new Maglev(getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.EulerSwapParams({px: px, py: py, cx: cx, cy: cy})); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); vm.prank(owner); maglev.configure(); - - vm.prank(owner); - maglev.setDebtLimit(50e18, 50e18); } + function test_basicSwap_exactIn() public monotonicHolderNAV { uint256 amountIn = 1e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); @@ -59,7 +57,7 @@ contract EulerSwapTest is MaglevTestBase { assertEq(assetTST2.balanceOf(address(this)), amountOut); } - function test_price() public { + function test_altPrice() public { uint256 price = 0.5e18; uint256 px = price; uint256 py = 1e18; @@ -68,8 +66,8 @@ contract EulerSwapTest is MaglevTestBase { int256 origNAV = getHolderNAV(); + createMaglev(50e18, 50e18, 0, px, py, 0.4e18, 0.85e18); vm.prank(owner); - maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: 0.4e18, cy: 0.85e18, fee: minFee})); uint256 amountIn = 1e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); @@ -121,8 +119,7 @@ contract EulerSwapTest is MaglevTestBase { oracle.setPrice(address(eTST), unitOfAccount, price); oracle.setPrice(address(assetTST), unitOfAccount, price); - vm.prank(owner); - maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: px, py: py, cx: cx, cy: cy, fee: minFee})); + createMaglev(50e18, 50e18, 0, px, py, cx, cy); int256 origNAV = getHolderNAV(); @@ -151,11 +148,6 @@ contract EulerSwapTest is MaglevTestBase { } function test_roundingFailure() public { - vm.skip(true); - - vm.prank(owner); - maglev.setEulerSwapParams(Maglev.EulerSwapParams({px: 1e18, py: 1e18, cx: 0.4e18, cy: 0.85e18, fee: 0})); - uint256 amountIn = 1.4e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index cd28a4f..76f65d6 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -42,9 +42,9 @@ contract MaglevTestBase is EVaultTestBase { _mintAndDeposit(holder, eTST2, 10e18); } - function _getMaglevBaseParams() internal view returns (MaglevBase.BaseParams memory) { + function getMaglevBaseParams(uint112 debtLimit0, uint112 debtLimit1, uint256 fee) internal view returns (MaglevBase.BaseParams memory) { return - MaglevBase.BaseParams({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder}); + MaglevBase.BaseParams({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder, debtLimit0: debtLimit0, debtLimit1: debtLimit1, fee: fee}); } function _mintAndDeposit(address who, IEVault vault, uint256 amount) internal { From fc1a7eea535bc10023c035517c7b792ecb2e23a5 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 13 Dec 2024 19:01:40 -0500 Subject: [PATCH 049/312] fmt --- src/MaglevBase.sol | 4 +--- src/MaglevConstantProduct.sol | 10 ++-------- src/MaglevConstantSum.sol | 7 +------ test/ConstantProduct.t.sol | 7 ++++--- test/ConstantSum.t.sol | 8 ++++++-- test/EulerSwap.t.sol | 16 +++++++++++++--- test/MaglevTestBase.t.sol | 17 ++++++++++++++--- 7 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 778bbd8..46b299e 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -214,9 +214,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { // To be implemented by sub-class - function verify(uint256 amount0In, uint256 amount1In, uint256 newReserve0, uint256 newReserve1) - internal - virtual; + function verify(uint256 amount0In, uint256 amount1In, uint256 newReserve0, uint256 newReserve1) internal virtual; function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view virtual returns (uint256); } diff --git a/src/MaglevConstantProduct.sol b/src/MaglevConstantProduct.sol index 996359a..05dbed7 100644 --- a/src/MaglevConstantProduct.sol +++ b/src/MaglevConstantProduct.sol @@ -6,19 +6,13 @@ import {MaglevBase} from "./MaglevBase.sol"; contract MaglevConstantProduct is MaglevBase { error KNotSatisfied(); - constructor(BaseParams memory baseParams) MaglevBase(baseParams) { - } + constructor(BaseParams memory baseParams) MaglevBase(baseParams) {} function k(uint256 r0, uint256 r1) public pure returns (uint256) { return r0 * r1; } - function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) - internal - view - virtual - override - { + function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) internal view virtual override { uint256 kBefore = k(reserve0, reserve1); uint256 kAfter = k(newReserve0, newReserve1); require(kAfter >= kBefore, KNotSatisfied()); diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index 9f9cfd9..f29138d 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -23,12 +23,7 @@ contract MaglevConstantSum is MaglevBase { return (r0 * priceA) + (r1 * priceB); } - function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) - internal - view - virtual - override - { + function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) internal view virtual override { uint256 kBefore = k(reserve0, reserve1); uint256 kAfter = k(newReserve0, newReserve1); require(kAfter >= kBefore, KNotSatisfied()); diff --git a/test/ConstantProduct.t.sol b/test/ConstantProduct.t.sol index 2e13d97..962460b 100644 --- a/test/ConstantProduct.t.sol +++ b/test/ConstantProduct.t.sol @@ -40,7 +40,7 @@ contract ConstantProductTest is MaglevTestBase { assetTST.transfer(address(maglev), amount); vm.expectRevert(Maglev.KNotSatisfied.selector); - maglev.swap(0, q+1, address(this), ""); + maglev.swap(0, q + 1, address(this), ""); maglev.swap(0, q, address(this), ""); assertEq(assetTST2.balanceOf(address(this)), q); @@ -67,8 +67,8 @@ contract ConstantProductTest is MaglevTestBase { t1.transfer(address(maglev), amount); vm.expectRevert(Maglev.KNotSatisfied.selector); - if (dir) maglev.swap(0, q+1, address(this), ""); - else maglev.swap(q+1, 0, address(this), ""); + if (dir) maglev.swap(0, q + 1, address(this), ""); + else maglev.swap(q + 1, 0, address(this), ""); if (dir) maglev.swap(0, q, address(this), ""); else maglev.swap(q, 0, address(this), ""); @@ -94,6 +94,7 @@ contract ConstantProductTest is MaglevTestBase { t2.transfer(address(maglev), q); if (dir) maglev.swap(amount - 2, 0, address(this), ""); // - 2 due to rounding + else maglev.swap(0, amount - 2, address(this), ""); uint256 q2 = maglev.quoteExactInput(address(t1), address(t2), amount); diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index 2e5d4bc..7deda28 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -19,9 +19,13 @@ contract ConstantSumTest is MaglevTestBase { createMaglev(50e18, 50e18, 0, 1, 1); } - function createMaglev(uint112 debtLimit0, uint112 debtLimit1, uint256 fee, uint256 priceA, uint256 priceB) internal { + function createMaglev(uint112 debtLimit0, uint112 debtLimit1, uint256 fee, uint256 priceA, uint256 priceB) + internal + { vm.prank(owner); - maglev = new Maglev(getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.ConstantSumParams({priceA: priceA, priceB: priceB})); + maglev = new Maglev( + getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.ConstantSumParams({priceA: priceA, priceB: priceB}) + ); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index caaf3aa..b3e3138 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -19,9 +19,19 @@ contract EulerSwapTest is MaglevTestBase { createMaglev(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); } - function createMaglev(uint112 debtLimit0, uint112 debtLimit1, uint256 fee, uint256 px, uint256 py, uint256 cx, uint256 cy) internal { + function createMaglev( + uint112 debtLimit0, + uint112 debtLimit1, + uint256 fee, + uint256 px, + uint256 py, + uint256 cx, + uint256 cy + ) internal { vm.prank(owner); - maglev = new Maglev(getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.EulerSwapParams({px: px, py: py, cx: cx, cy: cy})); + maglev = new Maglev( + getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.EulerSwapParams({px: px, py: py, cx: cx, cy: cy}) + ); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); @@ -30,7 +40,6 @@ contract EulerSwapTest is MaglevTestBase { maglev.configure(); } - function test_basicSwap_exactIn() public monotonicHolderNAV { uint256 amountIn = 1e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); @@ -147,6 +156,7 @@ contract EulerSwapTest is MaglevTestBase { assertGe(getHolderNAV(), origNAV); } + // To reproduce, change roundingCompensation to 1e18 function test_roundingFailure() public { uint256 amountIn = 1.4e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index 76f65d6..a175d9c 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -42,9 +42,20 @@ contract MaglevTestBase is EVaultTestBase { _mintAndDeposit(holder, eTST2, 10e18); } - function getMaglevBaseParams(uint112 debtLimit0, uint112 debtLimit1, uint256 fee) internal view returns (MaglevBase.BaseParams memory) { - return - MaglevBase.BaseParams({evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder, debtLimit0: debtLimit0, debtLimit1: debtLimit1, fee: fee}); + function getMaglevBaseParams(uint112 debtLimit0, uint112 debtLimit1, uint256 fee) + internal + view + returns (MaglevBase.BaseParams memory) + { + return MaglevBase.BaseParams({ + evc: address(evc), + vault0: address(eTST), + vault1: address(eTST2), + myAccount: holder, + debtLimit0: debtLimit0, + debtLimit1: debtLimit1, + fee: fee + }); } function _mintAndDeposit(address who, IEVault vault, uint256 amount) internal { From a81004a91129318784860e62a7d8574f1fd4206d Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 13 Dec 2024 23:24:27 -0500 Subject: [PATCH 050/312] more fuzz tests --- src/MaglevEulerSwap.sol | 1 - test/ConstantProduct.t.sol | 37 ++++++++++++++++++++++++++++++++++++ test/ConstantSum.t.sol | 1 - test/EulerSwap.t.sol | 39 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index 49fdad2..f3268cb 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -33,7 +33,6 @@ contract MaglevEulerSwap is MaglevBase { _cy = params.cy; } - // FIXME: how to charge fees? function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) internal view virtual override { int256 delta = 0; diff --git a/test/ConstantProduct.t.sol b/test/ConstantProduct.t.sol index 962460b..c36b572 100644 --- a/test/ConstantProduct.t.sol +++ b/test/ConstantProduct.t.sol @@ -100,4 +100,41 @@ contract ConstantProductTest is MaglevTestBase { uint256 q2 = maglev.quoteExactInput(address(t1), address(t2), amount); assertApproxEqAbs(q, q2, 2); } + + function test_fuzzAll(uint256 fee, uint256[8] calldata amounts, bool[8] calldata dirs) public { + fee = bound(fee, 0, 0.1e18); + + createMaglev(50e18, 50e18, fee); + + int256 origNAV = getHolderNAV(); + + for (uint256 i = 0; i < 8; i++) { + uint256 amount = bound(amounts[i], 0.1e18, 5e18); + bool dir = dirs[i]; + + TestERC20 t1; + TestERC20 t2; + if (dir) (t1, t2) = (assetTST, assetTST2); + else (t1, t2) = (assetTST2, assetTST); + + t1.mint(address(this), amount); + uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount); + + t1.transfer(address(maglev), amount); + + { + uint256 qPlus = q + 1; + vm.expectRevert(); + if (dir) maglev.swap(0, qPlus, address(this), ""); + else maglev.swap(qPlus, 0, address(this), ""); + } + + uint256 prevBal = t2.balanceOf(address(this)); + if (dir) maglev.swap(0, q, address(this), ""); + else maglev.swap(q, 0, address(this), ""); + assertEq(t2.balanceOf(address(this)), q + prevBal); + + assertGe(getHolderNAV(), origNAV); + } + } } diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index 7deda28..ff23414 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -170,7 +170,6 @@ contract ConstantSumTest is MaglevTestBase { uint256 feeMultiplier = 1e18 - fee; uint256 needed = (amount1 * 1e18 + (feeMultiplier - 1)) / feeMultiplier; - console.log(amount1, needed, fee); TestERC20 tt; TestERC20 tt2; diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index b3e3138..81b0b69 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -166,4 +166,43 @@ contract EulerSwapTest is MaglevTestBase { maglev.swap(0, amountOut, address(this), ""); assertEq(assetTST2.balanceOf(address(this)), amountOut); } + + function test_fuzzAll(uint256 cx, uint256 cy, uint256 fee, uint256[8] calldata amounts, bool[8] calldata dirs) public { + cx = bound(cx, 0.01e18, 0.99e18); + cy = bound(cy, 0.01e18, 0.99e18); + fee = bound(fee, 0, 0.1e18); + + createMaglev(50e18, 50e18, fee, 1e18, 1e18, cx, cy); + + int256 origNAV = getHolderNAV(); + + for (uint256 i = 0; i < 8; i++) { + uint256 amount = bound(amounts[i], 0.1e18, 5e18); + bool dir = dirs[i]; + + TestERC20 t1; + TestERC20 t2; + if (dir) (t1, t2) = (assetTST, assetTST2); + else (t1, t2) = (assetTST2, assetTST); + + t1.mint(address(this), amount); + uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount); + + t1.transfer(address(maglev), amount); + + { + uint256 qPlus = q * 1.0000000000002e18 / 1e18; + vm.expectRevert(); + if (dir) maglev.swap(0, qPlus, address(this), ""); + else maglev.swap(qPlus, 0, address(this), ""); + } + + uint256 prevBal = t2.balanceOf(address(this)); + if (dir) maglev.swap(0, q, address(this), ""); + else maglev.swap(q, 0, address(this), ""); + assertEq(t2.balanceOf(address(this)), q + prevBal); + + assertGe(getHolderNAV(), origNAV); + } + } } From a6e7c67571c37e3ab27c9d2cb3870372184cecf3 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 13 Dec 2024 23:26:18 -0500 Subject: [PATCH 051/312] simplify interface --- src/MaglevBase.sol | 4 ++-- src/MaglevConstantProduct.sol | 2 +- src/MaglevConstantSum.sol | 2 +- src/MaglevEulerSwap.sol | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 46b299e..ca6f667 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -114,7 +114,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { uint256 newReserve1 = reserve1 + amount1In - amount1Out; require(newReserve0 <= type(uint112).max && newReserve1 <= type(uint112).max, Overflow()); - verify(amount0In, amount1In, newReserve0, newReserve1); + verify(newReserve0, newReserve1); reserve0 = uint112(newReserve0); reserve1 = uint112(newReserve1); @@ -214,7 +214,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { // To be implemented by sub-class - function verify(uint256 amount0In, uint256 amount1In, uint256 newReserve0, uint256 newReserve1) internal virtual; + function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual; function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view virtual returns (uint256); } diff --git a/src/MaglevConstantProduct.sol b/src/MaglevConstantProduct.sol index 05dbed7..35169e8 100644 --- a/src/MaglevConstantProduct.sol +++ b/src/MaglevConstantProduct.sol @@ -12,7 +12,7 @@ contract MaglevConstantProduct is MaglevBase { return r0 * r1; } - function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) internal view virtual override { + function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override { uint256 kBefore = k(reserve0, reserve1); uint256 kAfter = k(newReserve0, newReserve1); require(kAfter >= kBefore, KNotSatisfied()); diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index f29138d..d82ce8c 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -23,7 +23,7 @@ contract MaglevConstantSum is MaglevBase { return (r0 * priceA) + (r1 * priceB); } - function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) internal view virtual override { + function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override { uint256 kBefore = k(reserve0, reserve1); uint256 kAfter = k(newReserve0, newReserve1); require(kAfter >= kBefore, KNotSatisfied()); diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index f3268cb..c57b241 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -33,7 +33,7 @@ contract MaglevEulerSwap is MaglevBase { _cy = params.cy; } - function verify(uint256, uint256, uint256 newReserve0, uint256 newReserve1) internal view virtual override { + function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override { int256 delta = 0; if (newReserve0 >= initialReserve0) { From 6fbe951fd7f1d004b0121c80fb4824cbdd0cbff9 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 13 Dec 2024 23:26:27 -0500 Subject: [PATCH 052/312] fmt --- test/EulerSwap.t.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 81b0b69..358a63c 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -167,7 +167,9 @@ contract EulerSwapTest is MaglevTestBase { assertEq(assetTST2.balanceOf(address(this)), amountOut); } - function test_fuzzAll(uint256 cx, uint256 cy, uint256 fee, uint256[8] calldata amounts, bool[8] calldata dirs) public { + function test_fuzzAll(uint256 cx, uint256 cy, uint256 fee, uint256[8] calldata amounts, bool[8] calldata dirs) + public + { cx = bound(cx, 0.01e18, 0.99e18); cy = bound(cy, 0.01e18, 0.99e18); fee = bound(fee, 0, 0.1e18); From 07e07c6a8b7e26f2b3c374a35141aa427d701b89 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 13 Dec 2024 23:32:23 -0500 Subject: [PATCH 053/312] initial reserves immutable --- src/MaglevBase.sol | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index ca6f667..8b72869 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -17,14 +17,13 @@ abstract contract MaglevBase is EVCUtil, Ownable { uint112 public immutable debtLimit0; uint112 public immutable debtLimit1; uint256 public immutable feeMultiplier; + uint112 public immutable initialReserve0; + uint112 public immutable initialReserve1; uint112 public reserve0; uint112 public reserve1; uint32 private locked; - uint112 public initialReserve0; - uint112 public initialReserve1; - error Reentrancy(); error Overflow(); error UnsupportedPair(); From bfbeed138ce1fc81e6e3fdeeb0f271e5c0269a8a Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 13 Dec 2024 23:57:50 -0500 Subject: [PATCH 054/312] cleanup --- src/MaglevBase.sol | 17 +++++++++--- src/MaglevConstantSum.sol | 17 ++++++------ src/MaglevEulerSwap.sol | 54 ++++++++++++++++++++++++++++----------- test/ConstantSum.t.sol | 4 +-- 4 files changed, 62 insertions(+), 30 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 8b72869..7b833f9 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; -import {console} from "forge-std/Test.sol"; import {Ownable, Context} from "openzeppelin-contracts/access/Ownable.sol"; import {EVCUtil} from "evc/utils/EVCUtil.sol"; import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; @@ -22,9 +21,9 @@ abstract contract MaglevBase is EVCUtil, Ownable { uint112 public reserve0; uint112 public reserve1; - uint32 private locked; + uint32 public locked; // 0=unlocked, 1=reentrancy guard, 2=paused - error Reentrancy(); + error Locked(); error Overflow(); error UnsupportedPair(); error BadFee(); @@ -32,7 +31,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { error InsufficientCash(); modifier nonReentrant() { - require(locked == 0, Reentrancy()); + require(locked == 0, Locked()); locked = 1; _; locked = 0; @@ -76,6 +75,16 @@ abstract contract MaglevBase is EVCUtil, Ownable { IEVC(evc).enableCollateral(myAccount, vault1); } + function pause() external onlyOwner { + require(locked == 0, Locked()); + locked = 2; + } + + function unpause() external onlyOwner { + require(locked == 2, Locked()); + locked = 0; + } + // Swapper interface function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index d82ce8c..b0cb273 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -4,23 +4,23 @@ pragma solidity ^0.8.27; import {MaglevBase} from "./MaglevBase.sol"; contract MaglevConstantSum is MaglevBase { - uint256 public immutable priceA; - uint256 public immutable priceB; + uint256 public immutable priceX; + uint256 public immutable priceY; error KNotSatisfied(); struct ConstantSumParams { - uint256 priceA; - uint256 priceB; + uint256 priceX; + uint256 priceY; } constructor(BaseParams memory baseParams, ConstantSumParams memory params) MaglevBase(baseParams) { - priceA = params.priceA; - priceB = params.priceB; + priceX = params.priceX; + priceY = params.priceY; } function k(uint256 r0, uint256 r1) public view returns (uint256) { - return (r0 * priceA) + (r1 * priceB); + return (r0 * priceX) + (r1 * priceY); } function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override { @@ -29,9 +29,8 @@ contract MaglevConstantSum is MaglevBase { require(kAfter >= kBefore, KNotSatisfied()); } - // FIXME: incorporate priceA and priceB - function computeQuote(uint256 amount, bool, bool) internal view virtual override returns (uint256) { + // FIXME: use priceX and priceY return amount; } } diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index c57b241..145a84d 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -1,15 +1,14 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; -import {console} from "forge-std/Test.sol"; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {MaglevBase} from "./MaglevBase.sol"; contract MaglevEulerSwap is MaglevBase { - uint256 public _px; - uint256 public _py; - uint256 public _cx; - uint256 public _cy; + uint256 public priceX; + uint256 public priceY; + uint256 public concentrationX; + uint256 public concentrationY; error KNotSatisfied(); error ReservesZero(); @@ -27,27 +26,32 @@ contract MaglevEulerSwap is MaglevBase { } function setEulerSwapParams(EulerSwapParams memory params) public onlyOwner { - _px = params.px; - _py = params.py; - _cx = params.cx; - _cy = params.cy; + priceX = params.px; + priceY = params.py; + concentrationX = params.cx; + concentrationY = params.cy; } + // Due to rounding, computeQuote() may underestimate the amount required to + // pass the verify() function. In order to prevent swaps from failing, quotes + // are inflated by this compensation factor. FIXME: solve the rounding. + uint256 private constant roundingCompensation = 1.0000000000001e18; + function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override { int256 delta = 0; if (newReserve0 >= initialReserve0) { - delta = int256(newReserve0) - int256(fy(newReserve1, _px, _py, initialReserve0, initialReserve1, _cx, _cy)); + delta = int256(newReserve0) + - int256(fy(newReserve1, priceX, priceY, initialReserve0, initialReserve1, concentrationX, concentrationY)); } else { - delta = int256(newReserve1) - int256(fx(newReserve0, _px, _py, initialReserve0, initialReserve1, _cx, _cy)); + delta = int256(newReserve1) + - int256(fx(newReserve0, priceX, priceY, initialReserve0, initialReserve1, concentrationX, concentrationY)); } // if delta is >= zero, then point is on or above the curve require(delta >= 0, KNotSatisfied()); } - uint256 private constant roundingCompensation = 1.0000000000001e18; - function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view @@ -72,11 +76,31 @@ contract MaglevEulerSwap is MaglevBase { if (dx != 0) { reserve0New += dx; - reserve1New = int256(fx(uint256(reserve0New), _px, _py, initialReserve0, initialReserve1, _cx, _cy)); + reserve1New = int256( + fx( + uint256(reserve0New), + priceX, + priceY, + initialReserve0, + initialReserve1, + concentrationX, + concentrationY + ) + ); } if (dy != 0) { reserve1New += dy; - reserve0New = int256(fy(uint256(reserve1New), _px, _py, initialReserve0, initialReserve1, _cx, _cy)); + reserve0New = int256( + fy( + uint256(reserve1New), + priceX, + priceY, + initialReserve0, + initialReserve1, + concentrationX, + concentrationY + ) + ); } dx = reserve0New - int256(uint256(reserve0)); diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index ff23414..1596a29 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -19,12 +19,12 @@ contract ConstantSumTest is MaglevTestBase { createMaglev(50e18, 50e18, 0, 1, 1); } - function createMaglev(uint112 debtLimit0, uint112 debtLimit1, uint256 fee, uint256 priceA, uint256 priceB) + function createMaglev(uint112 debtLimit0, uint112 debtLimit1, uint256 fee, uint256 priceX, uint256 priceY) internal { vm.prank(owner); maglev = new Maglev( - getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.ConstantSumParams({priceA: priceA, priceB: priceB}) + getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.ConstantSumParams({priceX: priceX, priceY: priceY}) ); vm.prank(holder); From 49a71de9b208455a2ac1b9cd1d1fa5a8c244465d Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 14 Dec 2024 00:20:18 -0500 Subject: [PATCH 055/312] cleanup --- src/MaglevEulerSwap.sol | 28 ++++++++++++---------------- test/EulerSwap.t.sol | 2 +- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index 145a84d..9ca92de 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -5,31 +5,27 @@ import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {MaglevBase} from "./MaglevBase.sol"; contract MaglevEulerSwap is MaglevBase { - uint256 public priceX; - uint256 public priceY; - uint256 public concentrationX; - uint256 public concentrationY; + uint256 public immutable priceX; + uint256 public immutable priceY; + uint256 public immutable concentrationX; + uint256 public immutable concentrationY; error KNotSatisfied(); error ReservesZero(); error InvalidInputCoordinate(); struct EulerSwapParams { - uint256 px; - uint256 py; - uint256 cx; - uint256 cy; + uint256 priceX; + uint256 priceY; + uint256 concentrationX; + uint256 concentrationY; } constructor(BaseParams memory baseParams, EulerSwapParams memory params) MaglevBase(baseParams) { - setEulerSwapParams(params); - } - - function setEulerSwapParams(EulerSwapParams memory params) public onlyOwner { - priceX = params.px; - priceY = params.py; - concentrationX = params.cx; - concentrationY = params.cy; + priceX = params.priceX; + priceY = params.priceY; + concentrationX = params.concentrationX; + concentrationY = params.concentrationY; } // Due to rounding, computeQuote() may underestimate the amount required to diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 358a63c..724215e 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -30,7 +30,7 @@ contract EulerSwapTest is MaglevTestBase { ) internal { vm.prank(owner); maglev = new Maglev( - getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.EulerSwapParams({px: px, py: py, cx: cx, cy: cy}) + getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.EulerSwapParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) ); vm.prank(holder); From ce82da0484957c38a779bfe83caa0a97cde9d6ae Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 14 Dec 2024 00:26:21 -0500 Subject: [PATCH 056/312] docs --- README.md | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e2aabee..8bb9561 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ ![maglev logo](docs/maglev.png) -Maglev is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) as leveraged lending products in order to extend the range of its reserves and thereby improve the capital efficiency of liquidity provisioning. +Maglev is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) to *mag*nify capital efficiency using *lev*erage. By borrowing assets as needed, maglev AMMs can extend the range of their reserves and earn fees on trades several times larger than their liquidity outlay. -To swappers, it presents a conventional Uniswap2-style interface but internally it supports custom pricing curves and other advanced functionality. +To swappers, maglev presents a conventional Uniswap2-style interface but internally it supports custom pricing curves and other advanced functionality. @@ -24,30 +24,41 @@ To swappers, it presents a conventional Uniswap2-style interface but internally ## Concept -Given a fixed size investment, Maglev aims to increase the size of trades that can be serviced, relative to a conventional AMM such as Uniswap. It does this by borrowing the "out token" and collateralising this loan with the received "in token". Later on, when somebody wishes to swap in the reverse direction, the loan can be repaid in exchange for receiving the collateral, unwinding the borrow position. +Given a fixed size investment, Maglev aims to increase the size of trades that can be serviced relative to a conventional AMM such as Uniswap. It does this by borrowing the "out token" and collateralising this loan with the received "in token". Later on, when somebody wishes to swap in the reverse direction, they repay the loan and receive the excess collateral, unwinding the borrow position. -Because the total size of the position can be many times larger than your initial investment (depending on how much LTV/leverage is allowed on the underlying lending pools), the swapping fees earned can be magnified. +Because the total size of the position can be many times larger than the initial investment (depending on how much LTV/leverage is allowed on the underlying lending pools), the swap fees earned can be magnified. -The down-side is that while the AMM holds this leveraged position, it is paying interest on the loan. Fortunately, this is partially compensated by the fact that the AMM is earning interest on the collateral. In addition, points and rewards may be earned on collateral/borrows. +The down-side is that while the AMM holds this leveraged position, it is paying interest on the loan. Fortunately, this is partially compensated by the fact that the AMM is simultaneously earning interest on the collateral. In some cases, this interest rate spread can be reduced further by taking advantage of incentives such as points/rewards. ## Operation -Since the level of acceptable borrowing risk may not be the same for every user, pooled deposits are not yet possible, and each Maglev instance manages funds for a single user (who of course may operate on behalf of pooled funds). +Since the level of acceptable borrowing risk is not be the same for every user, pooled deposits are not supported. Each Maglev instance manages funds for a single entity (who of course may be jointly owned). Maglev is a contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators). This means that the user, known as the *holder*, does not give up control over their funds to a smart contract, but instead retains it in their wallet. The holder can be any compatible address, including standard multisig wallets or even an EOA. +FIXME owner + ### Usage The following are the high-level steps required to use Maglev: -* Deposit funds into one or both of the vaults -* Deploy the desired Maglev contract, choosing parameters such as the vaults and the desired `fee` -* Calculate the desired [virtual reserves](#virtual-reserves) and set these values by invoking `setVirtualReserves()` +* Deposit funds into one or both of the vaults in proportion of the initial price +* Deploy the desired Maglev contract, choosing parameters such as the vaults, debt limits, and the desired `fee` * Install the Maglev contract as an operator for your account * Invoke the `configure()` function on the Maglev contract At this point, anyone can invoke `swap()` on the Maglev contract, and this will perform borrowing and transferring activity between the two vaults. +### Reconfiguration + +All user-configurable parameters are stored in immutable variables, meaning they cannot be changed after the AMM is deployed. Instead, the AMM should be uninstalled as an EVC operator, and a new Maglev instance should be created and installed in its place. + +In order to temporarily disable a Maglev instance, `pause()` and `unpause()` + +### Fees + +FIXME + ### Virtual Reserves The initial deposits in the vaults represent the initial investment, and are swapped back and forth in response to swapping activity. In a conventional AMM such as Uniswap, these balance are called *reserves*. However, if swapping was constrained to these assets alone, then this would imply a hard limit on the size of swaps that can be serviced. To increase the effective funds, Maglev AMMs are configured with *virtual reserves*. These are typically larger than the size of the conventional reserves, which signifies that not only can all the assets be swapped from one vault to another, but even more assets can be borrowed on the Maglev's account. From c4983f6c9f6fd67984e0d388a0848e98b40c4238 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 14 Dec 2024 01:10:25 -0500 Subject: [PATCH 057/312] no more owner --- src/MaglevBase.sol | 39 ++++++++++++-------------------------- test/ConstantProduct.t.sol | 4 ++-- test/ConstantSum.t.sol | 4 ++-- test/EulerSwap.t.sol | 5 ++--- test/MaglevTestBase.t.sol | 3 ++- 5 files changed, 20 insertions(+), 35 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 7b833f9..2d0f1b8 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -1,13 +1,12 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; -import {Ownable, Context} from "openzeppelin-contracts/access/Ownable.sol"; import {EVCUtil} from "evc/utils/EVCUtil.sol"; import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault, IERC20, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; import {IUniswapV2Callee} from "./interfaces/IUniswapV2Callee.sol"; -abstract contract MaglevBase is EVCUtil, Ownable { +abstract contract MaglevBase is EVCUtil { address public immutable vault0; address public immutable vault1; address public immutable asset0; @@ -21,7 +20,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { uint112 public reserve0; uint112 public reserve1; - uint32 public locked; // 0=unlocked, 1=reentrancy guard, 2=paused + uint32 public locked; error Locked(); error Overflow(); @@ -37,10 +36,6 @@ abstract contract MaglevBase is EVCUtil, Ownable { locked = 0; } - function _msgSender() internal view override(Context, EVCUtil) returns (address) { - return EVCUtil._msgSender(); - } - struct BaseParams { address evc; address vault0; @@ -51,7 +46,7 @@ abstract contract MaglevBase is EVCUtil, Ownable { uint256 fee; } - constructor(BaseParams memory params) EVCUtil(params.evc) Ownable(msg.sender) { + constructor(BaseParams memory params) EVCUtil(params.evc) { require(params.fee < 1e18, BadFee()); vault0 = params.vault0; @@ -59,15 +54,15 @@ abstract contract MaglevBase is EVCUtil, Ownable { asset0 = IEVault(vault0).asset(); asset1 = IEVault(vault1).asset(); myAccount = params.myAccount; - reserve0 = initialReserve0 = adjustReserve(params.debtLimit0, vault0); - reserve1 = initialReserve1 = adjustReserve(params.debtLimit1, vault1); + reserve0 = initialReserve0 = offsetReserve(params.debtLimit0, vault0); + reserve1 = initialReserve1 = offsetReserve(params.debtLimit1, vault1); feeMultiplier = 1e18 - params.fee; } // Owner functions /// @dev Call *after* installing as operator - function configure() external onlyOwner { + function configure() external { IERC20(asset0).approve(vault0, type(uint256).max); IERC20(asset1).approve(vault1, type(uint256).max); @@ -75,16 +70,6 @@ abstract contract MaglevBase is EVCUtil, Ownable { IEVC(evc).enableCollateral(myAccount, vault1); } - function pause() external onlyOwner { - require(locked == 0, Locked()); - locked = 2; - } - - function unpause() external onlyOwner { - require(locked == 2, Locked()); - locked = 0; - } - // Swapper interface function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) @@ -148,18 +133,18 @@ abstract contract MaglevBase is EVCUtil, Ownable { return shares == 0 ? 0 : IEVault(vault).convertToAssets(shares); } - function adjustReserve(uint112 reserve, address vault) internal view returns (uint112) { - uint256 adjusted; + function offsetReserve(uint112 reserve, address vault) internal view returns (uint112) { + uint256 offset; uint256 debt = myDebt(vault); if (debt != 0) { - adjusted = reserve > debt ? reserve - debt : 0; + offset = reserve > debt ? reserve - debt : 0; } else { - adjusted = reserve + myBalance(vault); + offset = reserve + myBalance(vault); } - require(adjusted <= type(uint112).max, Overflow()); - return uint112(adjusted); + require(offset <= type(uint112).max, Overflow()); + return uint112(offset); } function withdrawAssets(address vault, uint256 amount, address to) internal { diff --git a/test/ConstantProduct.t.sol b/test/ConstantProduct.t.sol index c36b572..47a8fbe 100644 --- a/test/ConstantProduct.t.sol +++ b/test/ConstantProduct.t.sol @@ -20,13 +20,13 @@ contract ConstantProductTest is MaglevTestBase { } function createMaglev(uint112 debtLimit0, uint112 debtLimit1, uint256 fee) internal { - vm.prank(owner); + vm.prank(creator); maglev = new Maglev(getMaglevBaseParams(debtLimit0, debtLimit1, fee)); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); - vm.prank(owner); + vm.prank(anyone); maglev.configure(); } diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index 1596a29..bd4ca05 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -22,7 +22,7 @@ contract ConstantSumTest is MaglevTestBase { function createMaglev(uint112 debtLimit0, uint112 debtLimit1, uint256 fee, uint256 priceX, uint256 priceY) internal { - vm.prank(owner); + vm.prank(creator); maglev = new Maglev( getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.ConstantSumParams({priceX: priceX, priceY: priceY}) ); @@ -30,7 +30,7 @@ contract ConstantSumTest is MaglevTestBase { vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); - vm.prank(owner); + vm.prank(anyone); maglev.configure(); } diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 724215e..654ca71 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -28,7 +28,7 @@ contract EulerSwapTest is MaglevTestBase { uint256 cx, uint256 cy ) internal { - vm.prank(owner); + vm.prank(creator); maglev = new Maglev( getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.EulerSwapParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) ); @@ -36,7 +36,7 @@ contract EulerSwapTest is MaglevTestBase { vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); - vm.prank(owner); + vm.prank(anyone); maglev.configure(); } @@ -76,7 +76,6 @@ contract EulerSwapTest is MaglevTestBase { int256 origNAV = getHolderNAV(); createMaglev(50e18, 50e18, 0, px, py, 0.4e18, 0.85e18); - vm.prank(owner); uint256 amountIn = 1e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index a175d9c..eb28099 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -11,9 +11,10 @@ import {MaglevBase} from "../src/MaglevBase.sol"; contract MaglevTestBase is EVaultTestBase { address public depositor = makeAddr("depositor"); - address public owner = makeAddr("owner"); + address public creator = makeAddr("creator"); address public holder = makeAddr("holder"); address public recipient = makeAddr("recipient"); + address public anyone = makeAddr("anyone"); function setUp() public virtual override { super.setUp(); From 0bdc428f6dcc92b2142353022e2813618967b0bd Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 14 Dec 2024 01:14:26 -0500 Subject: [PATCH 058/312] initialReserve is specific to EulerSwap curve --- src/MaglevBase.sol | 6 ++---- src/MaglevEulerSwap.sol | 5 +++++ test/ConstantSum.t.sol | 2 -- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 2d0f1b8..2629ddc 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -15,8 +15,6 @@ abstract contract MaglevBase is EVCUtil { uint112 public immutable debtLimit0; uint112 public immutable debtLimit1; uint256 public immutable feeMultiplier; - uint112 public immutable initialReserve0; - uint112 public immutable initialReserve1; uint112 public reserve0; uint112 public reserve1; @@ -54,8 +52,8 @@ abstract contract MaglevBase is EVCUtil { asset0 = IEVault(vault0).asset(); asset1 = IEVault(vault1).asset(); myAccount = params.myAccount; - reserve0 = initialReserve0 = offsetReserve(params.debtLimit0, vault0); - reserve1 = initialReserve1 = offsetReserve(params.debtLimit1, vault1); + reserve0 = offsetReserve(params.debtLimit0, vault0); + reserve1 = offsetReserve(params.debtLimit1, vault1); feeMultiplier = 1e18 - params.fee; } diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index 9ca92de..b56b72a 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -9,6 +9,8 @@ contract MaglevEulerSwap is MaglevBase { uint256 public immutable priceY; uint256 public immutable concentrationX; uint256 public immutable concentrationY; + uint112 public immutable initialReserve0; + uint112 public immutable initialReserve1; error KNotSatisfied(); error ReservesZero(); @@ -26,6 +28,9 @@ contract MaglevEulerSwap is MaglevBase { priceY = params.priceY; concentrationX = params.concentrationX; concentrationY = params.concentrationY; + + initialReserve0 = reserve0; + initialReserve1 = reserve1; } // Due to rounding, computeQuote() may underestimate the amount required to diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index bd4ca05..02f145a 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -58,8 +58,6 @@ contract ConstantSumTest is MaglevTestBase { } function test_reserveLimit() public monotonicHolderNAV { - assertEq(maglev.initialReserve0(), 60e18); - assertEq(maglev.initialReserve1(), 60e18); assertEq(maglev.reserve0(), 60e18); assertEq(maglev.reserve1(), 60e18); From ce830b995581227e95430dd7d524b702b88f4859 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 14 Dec 2024 01:15:12 -0500 Subject: [PATCH 059/312] docs wip --- README.md | 35 ++++++++++++++++++++--------------- TODO | 20 +++++++++----------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 8bb9561..d72038e 100644 --- a/README.md +++ b/README.md @@ -36,45 +36,45 @@ Since the level of acceptable borrowing risk is not be the same for every user, Maglev is a contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators). This means that the user, known as the *holder*, does not give up control over their funds to a smart contract, but instead retains it in their wallet. The holder can be any compatible address, including standard multisig wallets or even an EOA. -FIXME owner - ### Usage The following are the high-level steps required to use Maglev: * Deposit funds into one or both of the vaults in proportion of the initial price * Deploy the desired Maglev contract, choosing parameters such as the vaults, debt limits, and the desired `fee` + * Note * Install the Maglev contract as an operator for your account -* Invoke the `configure()` function on the Maglev contract +* Invoke the `configure()` function on the Maglev contract. This function can be invoked by anyone, and it is harmless to re-invoke it. At this point, anyone can invoke `swap()` on the Maglev contract, and this will perform borrowing and transferring activity between the two vaults. ### Reconfiguration -All user-configurable parameters are stored in immutable variables, meaning they cannot be changed after the AMM is deployed. Instead, the AMM should be uninstalled as an EVC operator, and a new Maglev instance should be created and installed in its place. +All user-configurable parameters are stored in immutable variables, meaning they cannot be changed after the AMM is deployed. Instead, the holder should be uninstalled it from its EVC operator set, and a new Maglev instance should be created and installed in its place. -In order to temporarily disable a Maglev instance, `pause()` and `unpause()` +### Debt Limits -### Fees +The initial deposits in the two vaults represent the initial investment, and are swapped back and forth in response to swapping activity. In order to prevent loss to arbitrage, the initial investment should be made in proportion to the price of the assets. -FIXME +In a conventional AMM such as Uniswap, the balances held by the contract are called *reserves*, and these represent a hard upper-bound on the amounts that can be swapped: In other words, no matter how much you are willing to pay, you can never receive more than the current reserve. -### Virtual Reserves +To increase the effective swappable amounts, not only will Maglev AMMs swap all their reserves, but they will internally borrow *more* of the desired token in order to service a swap. How much debt the AMM is willing to take depends on the configured debt limits. -The initial deposits in the vaults represent the initial investment, and are swapped back and forth in response to swapping activity. In a conventional AMM such as Uniswap, these balance are called *reserves*. However, if swapping was constrained to these assets alone, then this would imply a hard limit on the size of swaps that can be serviced. To increase the effective funds, Maglev AMMs are configured with *virtual reserves*. These are typically larger than the size of the conventional reserves, which signifies that not only can all the assets be swapped from one vault to another, but even more assets can be borrowed on the Maglev's account. +For example, if the initial investment has a NAV of $1000, and the debt limit is configured at $5000, then the maximum LTV loan that the AMM will support will be `5000/6000 = 0.8333`. In order to leave a safety buffer, it is recommended to choose a maximum LTV that is below the borrowing LTV of the vault. -Virtual reserves control the maximum debt that the Maglev contract will attempt to acquire on each of its two vaults. Each vault can be configured independently. +Each vault can have its own independent debt limit, which may be useful in case of vaults configured with asymmetric LTVs. -For example, if the initial investment has a NAV of $1000, and virtual reserves are configured at $5000 for each vault, then the maximum LTV loan that the AMM will support will be `5000/6000 = 0.8333`. In order to leave a safety buffer, it is recommended to select a maximum LTV that is below the borrowing LTV of the vault. +Note that it depends on the [curve](#curves) if the maximum LTV can actually be achieved. A constant product curve will only approach these reserve levels asymptotically, since each unit will get more and more expensive. With a constant sum curve, the LTV can be achieved precisely. -Note that it depends on the [curve](#curves) if the maximum LTV can actually be achieved. A constant product will only approach these reserve levels asymptotically, since each unit will get more and more expensive. However, with constant sum, this LTV can be achieved directly. +### Desynchronised Reserves -### Desynchronised Virtual Reserves - -The Maglev contract tracks what it believes the reserves to be by caching their values in storage. These reserves are updated on each swap. However, since the balance is not actually held by the Maglev contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest is accrued, or suddenly if the holder moves funds or the position is liquidated. +The Maglev contract tracks what it believes the reserves (amount available plus borrowable) to be by caching in storage. These reserves are updated on each swap. However, since the balance is not actually held by the Maglev contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest and fees are accrued, or suddenly if the holder moves funds or the position is liquidated. When this occurs, the `syncVirtualReserves()` should be invoked. This determines the actual balances (and debts) of the holder, and adjusts them by the configured virtual reserve levels. +### Fees + +FIXME ## Curves @@ -93,6 +93,11 @@ This is the traditional Uniswap2 curve that preserves the product of the two res +## Todo + +* Can/should current reserves be calculated dynamically based on balances/debts/debt limits? + + ## License (c) 2024 Euler Labs Ltd. diff --git a/TODO b/TODO index 529b23b..8bc696d 100644 --- a/TODO +++ b/TODO @@ -1,21 +1,22 @@ -* pause guardian -* events +! events * reserve change on each swap +! Better revert messages when a swap cannot be satisifed due to debt-limit/utilisation/etc + * currently it's an arithmetic underflow * ConstantSum: incorporate price multipliers in quote methods * natspec * permit2 instead of regular approval: measure gas savings -? onlyEVCAccountOwner -? should uniswapV2Call take _msgSender instead of msg.sender? - - I think no, since swap isn't intended to be EVC-compatible -? alternate curves -? registry contract -? transparent proxy so AMM address can stay constant +? pause guardian +? how should aggregators find instances + ? registry contract + ? fake registry contract that looks at the actually installed operators for a list of accounts + ? transparent proxy so AMM address can stay constant docs low-level detail of how system works for auditors how to add a curve information for aggregators how to maintain quotes off-chain, including tracking cash from VaultStatus logs of underlying vaults + note how EVK stores balance and debt in same storage slot tests prices/alternate decimals @@ -23,6 +24,3 @@ tests when exchange rate in vaults != 1 uniswap callback, flash swaps hitting reserve/utilisation limits - changing reserves - changing fees/prices - onlyOwner methods can't be called by others From 4cf1163c894f7676d8a33931324327ebcf01393e Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 14 Dec 2024 01:58:18 -0500 Subject: [PATCH 060/312] docs --- README.md | 45 ++++++++++++++++++++++++++++++++++++--------- TODO | 2 +- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d72038e..f925843 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,10 @@ The following are the high-level steps required to use Maglev: * Deposit funds into one or both of the vaults in proportion of the initial price * Deploy the desired Maglev contract, choosing parameters such as the vaults, debt limits, and the desired `fee` - * Note + * Note that the Maglev contract must be created after the funds are deposited, because its constructor will read the current debt and balances to setup its reserves cache * Install the Maglev contract as an operator for your account -* Invoke the `configure()` function on the Maglev contract. This function can be invoked by anyone, and it is harmless to re-invoke it. +* Invoke the `configure()` function on the Maglev contract + * This function can be invoked by anyone, and it is harmless to re-invoke it At this point, anyone can invoke `swap()` on the Maglev contract, and this will perform borrowing and transferring activity between the two vaults. @@ -68,34 +69,60 @@ Note that it depends on the [curve](#curves) if the maximum LTV can actually be ### Desynchronised Reserves -The Maglev contract tracks what it believes the reserves (amount available plus borrowable) to be by caching in storage. These reserves are updated on each swap. However, since the balance is not actually held by the Maglev contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest and fees are accrued, or suddenly if the holder moves funds or the position is liquidated. +The Maglev contract tracks what it believes the reserves (amount available plus borrowable) to be by caching in storage. These reserves are updated on each swap. However, since the balance is not actually held by the Maglev contract (it is simply an operator), the actual underlying debts and balances may get out of sync. This can happen gradually as interest and fees are accrued, or suddenly if the holder moves funds or the position is liquidated. -When this occurs, the `syncVirtualReserves()` should be invoked. This determines the actual balances (and debts) of the holder, and adjusts them by the configured virtual reserve levels. +Normally this is not a problem, because swapping will still occur on the static curve. However, if there is a significant decrease in NAV then the desired LTVs may be exceeded (since the debt limit becomes higher relative to the NAV). If there is a significant increase in NAV then the AMM may become less capital efficient. To reset this, the Maglev instance should be uninstalled as an EVC operator, and a new one created and installed in its place. ### Fees -FIXME +Maglev collects swap fees in the input token. + +When quoting exact input swaps the effective input amount is decreased by the fee (rounding down) before consulting the curve. When quoting exact output swaps, the required input amount is increased by the fee (rounding up). + +After depositing but prior to verifying the curve invariant, all input amounts are adjusted down (rounding down). + +Since the full amount including fees is actually deposited (or repayed), fees have the effect of increasing the NAV of the position. However, they are not currently "fed back" into the reserves to be used by future swaps. If fees build up significantly, the Maglev instance should be [replaced](#desynchronised-reserves). ## Curves ### Constant Sum -This "curve" simply adds the values of the two reserves together and ensures that after a swap this sum has not decreased. This curve is mostly suitable for assets that are pegged to the same value, such as stable/stable pairs. +This "curve" simply adds the values of the two reserves together and ensures that after a swap this sum has not decreased. It is mostly suitable for assets that are pegged to the same value, such as stable-stable pairs. This curve supports a price fraction so that the two tokens can have different relative values, which can be useful if the peg is other than 1:1, or if the tokens have differing decimals. -In this curve, the entire virtual reserves can be consumed, and since each marginal unit of the swap has the same price, there is no direct incentive to deleverage the position. However, for the same reason this does allow fixed fees for swaps of any allowed size (fixed price impact). +In this curve, the entire virtual reserves can be consumed, and since each marginal unit of the swap has the same price, there is no direct incentive to deleverage the position. However, for the same reason this does allow fixed-size fees for swaps of any supported size (fixed price impact). ### Constant Product -This is the traditional Uniswap2 curve that preserves the product of the two reserves. The larger a swap, the higher the price impact and the more profitable it is to arbitrage a disbalanced pool back to its wider market price. +This is the traditional Uniswap2 curve that preserves the product of the two reserves. The larger a swap, the higher the price impact and the more profitable it is to arbitrage a disbalanced pool back to the market price. + +### EulerSwap Curve + +This is a new curve developed by Euler. It can be thought of as a hybrid between constant sum and constant product. The curve is defined piecewise: A piece to the left of an "initial reserves" point, and a piece to the right. + +Each piece has a `concentration` parameter that determines the trade-off between constant sum and constant product. The higher the concentration (closer to 1), the more it is similar to a constant sum, and the lower (closer to 0), constant product. The curve is also parameterise by a `price` parameter which determines the slope at the initial reserves point. There are actually two price parameters which can be considered the numerator and denominator of the price fraction. + +With careful parameter selection, the EulerSwap curve supports optimal tradeoffs between capital efficiency and arbitrage incentives. ## Todo -* Can/should current reserves be calculated dynamically based on balances/debts/debt limits? +* The EulerSwap curve has some numerical instability that we believe is caused by rounding + * We think the biggest effect is that it may cause some swaps to fail even if the the quoted amount is provided. Also, it may result in users slightly overpaying for swaps. + * The code currently has a roundingCompensation adjustment that seems to prevent this, but since we don't know a hard upper-bound it's hard to say if this solves it in all cases +* Currently we have only been supporting stable-stable pairs + * What extra considerations would there be for floating pairs? +* Automatically re-invest fees. There are a few options: + * Don't do anything: Re-deploing probably isn't a huge deal + * Increase the reserves by the fee amount + * Increase the reserves by the extra amount of possible leverage supported by the new fee + * Apply fees to a super-concentrated section of the curve (needs R&D) +* Could current reserves be calculated dynamically based on balances/debts/debt limits? + * I guess you would lose a chunk of interest to arbitrage + * Donation attacks? ## License diff --git a/TODO b/TODO index 8bc696d..a6cb01e 100644 --- a/TODO +++ b/TODO @@ -7,7 +7,7 @@ * permit2 instead of regular approval: measure gas savings ? pause guardian ? how should aggregators find instances - ? registry contract + ? factory/registry contract ? fake registry contract that looks at the actually installed operators for a list of accounts ? transparent proxy so AMM address can stay constant From 4f43adf2b5e6db51390b91c60d014de038aedfe7 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 14 Dec 2024 02:01:46 -0500 Subject: [PATCH 061/312] docs --- README.md | 14 +++++++++----- test/EulerSwap.t.sol | 3 ++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f925843..b6f543b 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # Euler Maglev -![maglev logo](docs/maglev.png) +![Maglev logo](docs/maglev.png) -Maglev is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) to *mag*nify capital efficiency using *lev*erage. By borrowing assets as needed, maglev AMMs can extend the range of their reserves and earn fees on trades several times larger than their liquidity outlay. +Maglev is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) to *mag*nify capital efficiency using *lev*erage. By borrowing assets as needed, Maglev AMMs can extend the range of their reserves and earn fees on trades several times larger than their liquidity outlay. -To swappers, maglev presents a conventional Uniswap2-style interface but internally it supports custom pricing curves and other advanced functionality. +To swappers, Maglev presents a conventional Uniswap2-style interface but internally it supports custom pricing curves and other advanced functionality. Although useable by anyone, the primary swapper user-base is intended to be aggregators, intents solvers, and MEV bots. @@ -13,11 +13,15 @@ To swappers, maglev presents a conventional Uniswap2-style interface but interna * [Concept](#concept) * [Operation](#operation) * [Usage](#usage) - * [Virtual Reserves](#virtual-reserves) - * [Desynchronised Virtual Reserves](#desynchronised-virtual-reserves) + * [Reconfiguration](#reconfiguration) + * [Debt Limits](#debt-limits) + * [Desynchronised Reserves](#desynchronised-reserves) + * [Fees](#fees) * [Curves](#curves) * [Constant Sum](#constant-sum) * [Constant Product](#constant-product) + * [EulerSwap Curve](#eulerswap-curve) +* [Todo](#todo) * [License](#license) diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 654ca71..2e81b00 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -30,7 +30,8 @@ contract EulerSwapTest is MaglevTestBase { ) internal { vm.prank(creator); maglev = new Maglev( - getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.EulerSwapParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) + getMaglevBaseParams(debtLimit0, debtLimit1, fee), + Maglev.EulerSwapParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) ); vm.prank(holder); From f3e6c8449cac069d7b15f075c1a7b926f2957dcf Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 14 Dec 2024 02:08:16 -0500 Subject: [PATCH 062/312] docs --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index b6f543b..d0a7c4f 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,11 @@ With careful parameter selection, the EulerSwap curve supports optimal tradeoffs * Could current reserves be calculated dynamically based on balances/debts/debt limits? * I guess you would lose a chunk of interest to arbitrage * Donation attacks? +* What can we do to make this easily integrated with aggregators/MEV bots/etc? + * For sure we need events. What should be logged? + * How to handle a discovery/tracking of the different Maglev instances? + * Factory? Registry? Maybe a fake factory that reads the actually installed operators from a set of addresses? +* Other misc stuff (see `TODO` file) ## License From 392383785f7b9f0f9124a6ea52da9f05b015a4af Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 14 Dec 2024 02:29:20 -0500 Subject: [PATCH 063/312] docs --- README.md | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index d0a7c4f..e54e69f 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ ![Maglev logo](docs/maglev.png) -Maglev is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) to *mag*nify capital efficiency using *lev*erage. By borrowing assets as needed, Maglev AMMs can extend the range of their reserves and earn fees on trades several times larger than their liquidity outlay. +Maglev is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) to **mag**nify capital efficiency using **lev**erage. By borrowing assets as needed, Maglev AMMs can extend the range of their reserves and earn fees on trades several times larger than their actual liquidity. -To swappers, Maglev presents a conventional Uniswap2-style interface but internally it supports custom pricing curves and other advanced functionality. Although useable by anyone, the primary swapper user-base is intended to be aggregators, intents solvers, and MEV bots. +To swappers, Maglev presents a conventional Uniswap2-style interface but internally it supports borrow and repaying, custom pricing curves, and other advanced functionality. Although invokeable by anyone, the primary swapper user-base is intended to be aggregators, intents solvers, and MEV bots. @@ -22,17 +22,19 @@ To swappers, Maglev presents a conventional Uniswap2-style interface but interna * [Constant Product](#constant-product) * [EulerSwap Curve](#eulerswap-curve) * [Todo](#todo) +* [See Also](#see-also) + * [Prior Art](#prior-art) * [License](#license) ## Concept -Given a fixed size investment, Maglev aims to increase the size of trades that can be serviced relative to a conventional AMM such as Uniswap. It does this by borrowing the "out token" and collateralising this loan with the received "in token". Later on, when somebody wishes to swap in the reverse direction, they repay the loan and receive the excess collateral, unwinding the borrow position. +Given a fixed size investment, Maglev aims to increase the size of trades that can be serviced relative to a conventional AMM such as Uniswap. It does this by borrowing the "out token" and collateralising this loan with the received "in token". Later on, when somebody wishes to swap in the reverse direction, their "in token" repays the loan and the excess collateral is sent as the "out token", thereby unwinding the position. -Because the total size of the position can be many times larger than the initial investment (depending on how much LTV/leverage is allowed on the underlying lending pools), the swap fees earned can be magnified. +Because the total size of the position can be many times larger than the initial investment (depending on how much LTV/leverage is allowed on the underlying lending pools), the swap fees earned are multiplied. -The down-side is that while the AMM holds this leveraged position, it is paying interest on the loan. Fortunately, this is partially compensated by the fact that the AMM is simultaneously earning interest on the collateral. In some cases, this interest rate spread can be reduced further by taking advantage of incentives such as points/rewards. +The down-side is that while the AMM holds this leveraged position, it is paying interest on the loan. Fortunately, this is partially compensated by the fact that the AMM is simultaneously earning interest on the collateral. In some cases, this interest rate spread can be reduced further (occasionally even going negative) by taking advantage of incentives such as points/rewards. ## Operation @@ -46,7 +48,7 @@ The following are the high-level steps required to use Maglev: * Deposit funds into one or both of the vaults in proportion of the initial price * Deploy the desired Maglev contract, choosing parameters such as the vaults, debt limits, and the desired `fee` - * Note that the Maglev contract must be created after the funds are deposited, because its constructor will read the current debt and balances to setup its reserves cache + * Note that the Maglev contract must be created after the funds are deposited, because its constructor will read the current debts and balances to setup its reserves cache * Install the Maglev contract as an operator for your account * Invoke the `configure()` function on the Maglev contract * This function can be invoked by anyone, and it is harmless to re-invoke it @@ -55,19 +57,19 @@ At this point, anyone can invoke `swap()` on the Maglev contract, and this will ### Reconfiguration -All user-configurable parameters are stored in immutable variables, meaning they cannot be changed after the AMM is deployed. Instead, the holder should be uninstalled it from its EVC operator set, and a new Maglev instance should be created and installed in its place. +All user-configurable parameters are stored in immutable variables, meaning they cannot be changed after the AMM is deployed. Instead, the holder should uninstalled it from its EVC operator set, and a new Maglev instance should be created and installed in its place. ### Debt Limits The initial deposits in the two vaults represent the initial investment, and are swapped back and forth in response to swapping activity. In order to prevent loss to arbitrage, the initial investment should be made in proportion to the price of the assets. -In a conventional AMM such as Uniswap, the balances held by the contract are called *reserves*, and these represent a hard upper-bound on the amounts that can be swapped: In other words, no matter how much you are willing to pay, you can never receive more than the current reserve. +In a conventional AMM such as Uniswap, the balances held by the contract are called *reserves*, and these represent a hard upper-bound on the amounts that can be swapped: In other words, no matter how much you are willing to pay, you can never receive more than the amount currently held in reserve. To increase the effective swappable amounts, not only will Maglev AMMs swap all their reserves, but they will internally borrow *more* of the desired token in order to service a swap. How much debt the AMM is willing to take depends on the configured debt limits. For example, if the initial investment has a NAV of $1000, and the debt limit is configured at $5000, then the maximum LTV loan that the AMM will support will be `5000/6000 = 0.8333`. In order to leave a safety buffer, it is recommended to choose a maximum LTV that is below the borrowing LTV of the vault. -Each vault can have its own independent debt limit, which may be useful in case of vaults configured with asymmetric LTVs. +Each vault can have its own independent debt limit, which may be useful in case of vaults configured with asymmetric LTVs. A debt limit of 0 could be specified for one of the vaults if the holder only ever wants a borrow position in one of the assets. In the future we may add a debt minimum, allowing the holder to retain a position within a certain leverage range while continuing to profit off swapping activity. Note that it depends on the [curve](#curves) if the maximum LTV can actually be achieved. A constant product curve will only approach these reserve levels asymptotically, since each unit will get more and more expensive. With a constant sum curve, the LTV can be achieved precisely. @@ -75,7 +77,7 @@ Note that it depends on the [curve](#curves) if the maximum LTV can actually be The Maglev contract tracks what it believes the reserves (amount available plus borrowable) to be by caching in storage. These reserves are updated on each swap. However, since the balance is not actually held by the Maglev contract (it is simply an operator), the actual underlying debts and balances may get out of sync. This can happen gradually as interest and fees are accrued, or suddenly if the holder moves funds or the position is liquidated. -Normally this is not a problem, because swapping will still occur on the static curve. However, if there is a significant decrease in NAV then the desired LTVs may be exceeded (since the debt limit becomes higher relative to the NAV). If there is a significant increase in NAV then the AMM may become less capital efficient. To reset this, the Maglev instance should be uninstalled as an EVC operator, and a new one created and installed in its place. +Normally this is not a problem, because swapping will still occur on the static curve (such actions do not change the offered prices). However, if there is a significant decrease in NAV then the desired LTVs may be exceeded (since the debt limit becomes higher relative to the NAV). If there is a significant increase in NAV then the AMM may become less capital efficient. To resynchronise, the Maglev instance should be uninstalled as an EVC operator, and a new one created and installed in its place. ### Fees @@ -85,7 +87,7 @@ When quoting exact input swaps the effective input amount is decreased by the fe After depositing but prior to verifying the curve invariant, all input amounts are adjusted down (rounding down). -Since the full amount including fees is actually deposited (or repayed), fees have the effect of increasing the NAV of the position. However, they are not currently "fed back" into the reserves to be used by future swaps. If fees build up significantly, the Maglev instance should be [replaced](#desynchronised-reserves). +Since the full amount including fees is actually deposited (or repaid), fees have the effect of increasing the NAV of the position. However, they are not currently "fed back" into the reserves to be used by future swaps. If fees build up significantly, the Maglev instance should be [replaced](#desynchronised-reserves). ## Curves @@ -96,7 +98,7 @@ This "curve" simply adds the values of the two reserves together and ensures tha This curve supports a price fraction so that the two tokens can have different relative values, which can be useful if the peg is other than 1:1, or if the tokens have differing decimals. -In this curve, the entire virtual reserves can be consumed, and since each marginal unit of the swap has the same price, there is no direct incentive to deleverage the position. However, for the same reason this does allow fixed-size fees for swaps of any supported size (fixed price impact). +In this curve, the entire virtual reserves can be consumed, and since each marginal unit of the swap has the same price, there is no direct incentive for arbitrageurs to deleverage the position. However, for the same reason this does allow fixed-size fees for swaps of any supported size (fixed price impact). ### Constant Product @@ -106,7 +108,7 @@ This is the traditional Uniswap2 curve that preserves the product of the two res This is a new curve developed by Euler. It can be thought of as a hybrid between constant sum and constant product. The curve is defined piecewise: A piece to the left of an "initial reserves" point, and a piece to the right. -Each piece has a `concentration` parameter that determines the trade-off between constant sum and constant product. The higher the concentration (closer to 1), the more it is similar to a constant sum, and the lower (closer to 0), constant product. The curve is also parameterise by a `price` parameter which determines the slope at the initial reserves point. There are actually two price parameters which can be considered the numerator and denominator of the price fraction. +Each piece has a `concentration` parameter that determines the trade-off between constant sum and constant product. The higher the concentration (closer to 1), the more it is similar to a constant sum, and the lower (closer to 0), a constant product. The curve is also parameterised by a `price` parameter which determines the slope at the initial reserves point. There are actually two price parameters which can be considered the numerator and denominator of the price fraction. With careful parameter selection, the EulerSwap curve supports optimal tradeoffs between capital efficiency and arbitrage incentives. @@ -115,7 +117,7 @@ With careful parameter selection, the EulerSwap curve supports optimal tradeoffs ## Todo * The EulerSwap curve has some numerical instability that we believe is caused by rounding - * We think the biggest effect is that it may cause some swaps to fail even if the the quoted amount is provided. Also, it may result in users slightly overpaying for swaps. + * We think the biggest effect is that it may cause some swaps to fail even if the exact quoted amount is sent. Also, it may result in users slightly overpaying for swaps. * The code currently has a roundingCompensation adjustment that seems to prevent this, but since we don't know a hard upper-bound it's hard to say if this solves it in all cases * Currently we have only been supporting stable-stable pairs * What extra considerations would there be for floating pairs? @@ -123,7 +125,7 @@ With careful parameter selection, the EulerSwap curve supports optimal tradeoffs * Don't do anything: Re-deploing probably isn't a huge deal * Increase the reserves by the fee amount * Increase the reserves by the extra amount of possible leverage supported by the new fee - * Apply fees to a super-concentrated section of the curve (needs R&D) + * Apply fees to a super-concentrated middle section of the curve (needs R&D) * Could current reserves be calculated dynamically based on balances/debts/debt limits? * I guess you would lose a chunk of interest to arbitrage * Donation attacks? @@ -134,6 +136,13 @@ With careful parameter selection, the EulerSwap curve supports optimal tradeoffs * Other misc stuff (see `TODO` file) +## See Also + +### Prior Art + +* [Blackhole swap](https://blackholeswap.com/documents/en.pdf): Essentially the same concept, but using a less optimal curve and hardcoded to two Compound pools. + + ## License (c) 2024 Euler Labs Ltd. From 1838ed345673027317a21daf5250273aa63176cc Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:15:55 +0700 Subject: [PATCH 064/312] add interfaces --- .gitignore | 3 +++ src/MaglevBase.sol | 3 ++- src/MaglevEulerSwap.sol | 3 ++- src/interfaces/IMaglevBase.sol | 20 ++++++++++++++++++++ src/interfaces/IMaglevEulerSwap.sol | 13 +++++++++++++ 5 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 src/interfaces/IMaglevBase.sol create mode 100644 src/interfaces/IMaglevEulerSwap.sol diff --git a/.gitignore b/.gitignore index 3269660..64c78d5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ out/ # Dotenv file .env + +# Coverage file +lcov.info \ No newline at end of file diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 2629ddc..269006e 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -5,8 +5,9 @@ import {EVCUtil} from "evc/utils/EVCUtil.sol"; import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault, IERC20, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; import {IUniswapV2Callee} from "./interfaces/IUniswapV2Callee.sol"; +import {IMaglevBase} from "./interfaces/IMaglevBase.sol"; -abstract contract MaglevBase is EVCUtil { +abstract contract MaglevBase is IMaglevBase, EVCUtil { address public immutable vault0; address public immutable vault1; address public immutable asset0; diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index b56b72a..3d8aa04 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -3,8 +3,9 @@ pragma solidity ^0.8.27; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {MaglevBase} from "./MaglevBase.sol"; +import {IMaglevEulerSwap} from "./interfaces/IMaglevEulerSwap.sol"; -contract MaglevEulerSwap is MaglevBase { +contract MaglevEulerSwap is IMaglevEulerSwap, MaglevBase { uint256 public immutable priceX; uint256 public immutable priceY; uint256 public immutable concentrationX; diff --git a/src/interfaces/IMaglevBase.sol b/src/interfaces/IMaglevBase.sol new file mode 100644 index 0000000..0bc4dcc --- /dev/null +++ b/src/interfaces/IMaglevBase.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +interface IMaglevBase { + function configure() external; + function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; + function quoteExactInput(address tokenIn, address tokenOut, uint256 amountIn) external view returns (uint256); + function quoteExactOutput(address tokenIn, address tokenOut, uint256 amountOut) external view returns (uint256); + + function vault0() external view returns (address); + function vault1() external view returns (address); + function asset0() external view returns (address); + function asset1() external view returns (address); + function myAccount() external view returns (address); + function debtLimit0() external view returns (uint112); + function debtLimit1() external view returns (uint112); + function feeMultiplier() external view returns (uint256); + function reserve0() external view returns (uint112); + function reserve1() external view returns (uint112); +} diff --git a/src/interfaces/IMaglevEulerSwap.sol b/src/interfaces/IMaglevEulerSwap.sol new file mode 100644 index 0000000..3902449 --- /dev/null +++ b/src/interfaces/IMaglevEulerSwap.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +import {IMaglevBase} from "./IMaglevBase.sol"; + +interface IMaglevEulerSwap is IMaglevBase { + function priceX() external view returns (uint256); + function priceY() external view returns (uint256); + function concentrationX() external view returns (uint256); + function concentrationY() external view returns (uint256); + function initialReserve0() external view returns (uint112); + function initialReserve1() external view returns (uint112); +} From 33d1b8da1a417abe171fcd7db3bb1f88ba8b9fa3 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:17:03 +0700 Subject: [PATCH 065/312] require asset0 != asset1 --- src/MaglevBase.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 269006e..9207d1d 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -52,6 +52,9 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { vault1 = params.vault1; asset0 = IEVault(vault0).asset(); asset1 = IEVault(vault1).asset(); + + require(asset0 != asset1, UnsupportedPair()); + myAccount = params.myAccount; reserve0 = offsetReserve(params.debtLimit0, vault0); reserve1 = offsetReserve(params.debtLimit1, vault1); From 3a4f1ef63dac68b14837fa3876c916956ed48c33 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 16 Dec 2024 19:36:56 +0700 Subject: [PATCH 066/312] use _msgSender() instead of msg.sender --- src/MaglevBase.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 9207d1d..f799be8 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -86,7 +86,7 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { // Invoke callback - if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data); + if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(_msgSender(), amount0Out, amount1Out, data); // Deposit all available funds, adjust received amounts downward to collect fees From 7f2e434ef60c761c8aecf97316ecd4ac9f838a5f Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Tue, 17 Dec 2024 18:02:24 +0700 Subject: [PATCH 067/312] UniswapV2Call.t.sol --- test/UniswapV2Call.t.sol | 83 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 test/UniswapV2Call.t.sol diff --git a/test/UniswapV2Call.t.sol b/test/UniswapV2Call.t.sol new file mode 100644 index 0000000..11516d3 --- /dev/null +++ b/test/UniswapV2Call.t.sol @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; + +import {IUniswapV2Callee} from "../src/interfaces/IUniswapV2Callee.sol"; +// import {Test, console} from "forge-std/Test.sol"; +import {MaglevTestBase} from "./MaglevTestBase.t.sol"; +import {MaglevEulerSwap as Maglev} from "../src/MaglevEulerSwap.sol"; + +contract UniswapV2CallTest is MaglevTestBase { + Maglev public maglev; + SwapCallbackTest swapCallback; + + function setUp() public virtual override { + super.setUp(); + + createMaglev(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + + swapCallback = new SwapCallbackTest(); + } + + function createMaglev( + uint112 debtLimit0, + uint112 debtLimit1, + uint256 fee, + uint256 px, + uint256 py, + uint256 cx, + uint256 cy + ) internal { + vm.prank(creator); + maglev = new Maglev( + getMaglevBaseParams(debtLimit0, debtLimit1, fee), + Maglev.EulerSwapParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) + ); + + vm.prank(holder); + evc.setAccountOperator(holder, address(maglev), true); + + vm.prank(anyone); + maglev.configure(); + } + + function test_callback() public { + uint256 amountIn = 1e18; + uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); + assertApproxEqAbs(amountOut, 0.9974e18, 0.0001e18); + + assetTST.mint(address(this), amountIn); + assetTST.transfer(address(maglev), amountIn); + + uint256 randomBalance = 3e18; + vm.prank(anyone); + swapCallback.executeSwap(maglev, 0, amountOut, abi.encode(randomBalance)); + assertEq(assetTST2.balanceOf(address(swapCallback)), amountOut); + assertEq(swapCallback.callbackSender(), address(swapCallback)); + assertEq(swapCallback.callbackAmount0(), 0); + assertEq(swapCallback.callbackAmount1(), amountOut); + assertEq(swapCallback.randomBalance(), randomBalance); + } +} + +contract SwapCallbackTest is IUniswapV2Callee { + address public callbackSender; + uint256 public callbackAmount0; + uint256 public callbackAmount1; + uint256 public randomBalance; + + function executeSwap(Maglev maglev, uint256 amountIn, uint256 amountOut, bytes calldata data) external { + maglev.swap(amountIn, amountOut, address(this), data); + } + + function uniswapV2Call(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external { + randomBalance = abi.decode(data, (uint256)); + + callbackSender = sender; + callbackAmount0 = amount0; + callbackAmount1 = amount1; + } + + function test_avoid_coverage() public pure { + return; + } +} From 16c81b3f88a54fa3dd62256027247302a728a424 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:56:05 +0700 Subject: [PATCH 068/312] MaglevEulerSwapFactory --- src/MaglevEulerSwapFactory.sol | 97 ++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/MaglevEulerSwapFactory.sol diff --git a/src/MaglevEulerSwapFactory.sol b/src/MaglevEulerSwapFactory.sol new file mode 100644 index 0000000..61b3b06 --- /dev/null +++ b/src/MaglevEulerSwapFactory.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.27; + +import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; +import {MaglevEulerSwap as Maglev, MaglevBase} from "./MaglevEulerSwap.sol"; + +/// @title MaglevEulerSwapRegistry contract +/// @custom:security-contact security@euler.xyz +/// @author Euler Labs (https://www.eulerlabs.com/) +contract MaglevEulerSwapFactory is Ownable { + event PoolDeployed(address indexed asset0, address indexed asset1, uint256 indexed feeMultiplier, address pool); + + error InvalidQuery(); + error PoolAlreadyDeployed(); + + /// @dev EVC address. + address public immutable evc; + /// @dev An array to store all pools addresses. + address[] public allPools; + /// @dev Mapping from asset0/asset1/fee => pool address. + mapping(address => mapping(address => mapping(uint256 => address))) public getPool; + + constructor(address evcAddr) Ownable(msg.sender) { + evc = evcAddr; + } + + /// @notice Deploy EulerSwap pool. + function deployPool( + address vault0, + address vault1, + address holder, + uint112 debtLimit0, + uint112 debtLimit1, + uint256 fee, + uint256 priceX, + uint256 priceY, + uint256 concentrationX, + uint256 concentrationY + ) external onlyOwner returns (address) { + Maglev pool = new Maglev( + MaglevBase.BaseParams({ + evc: address(evc), + vault0: vault0, + vault1: vault1, + myAccount: holder, + debtLimit0: debtLimit0, + debtLimit1: debtLimit1, + fee: fee + }), + Maglev.EulerSwapParams({ + priceX: priceX, + priceY: priceY, + concentrationX: concentrationX, + concentrationY: concentrationY + }) + ); + + address poolAsset0 = pool.asset0(); + address poolAsset1 = pool.asset1(); + uint256 feeMultiplier = pool.feeMultiplier(); + + require(getPool[poolAsset0][poolAsset1][feeMultiplier] == address(0), PoolAlreadyDeployed()); + + getPool[poolAsset0][poolAsset1][feeMultiplier] = address(pool); + // populate mapping in the reverse direction, deliberate choice to avoid the cost of comparing addresses + getPool[poolAsset1][poolAsset0][feeMultiplier] = address(pool); + + allPools.push(address(pool)); + + emit PoolDeployed(poolAsset0, poolAsset1, feeMultiplier, address(pool)); + + return address(pool); + } + + /// @notice Get the length of `allPools` array. + /// @return `allPools` length. + function allPoolsLength() external view returns (uint256) { + return allPools.length; + } + + /// @notice Get a slice of the registered pools array. + /// @param _start Start index of the slice. + /// @param _end End index of the slice. + /// @return An array containing the slice of the registered pools. + function getAllPoolsListSlice(uint256 _start, uint256 _end) external view returns (address[] memory) { + uint256 length = allPools.length; + if (_end == type(uint256).max) _end = length; + if (_end < _start || _end > length) revert InvalidQuery(); + + address[] memory allPoolsList = new address[](_end - _start); + for (uint256 i; i < _end - _start; ++i) { + allPoolsList[i] = allPools[_start + i]; + } + + return allPoolsList; + } +} From cdfbfbe274ce24a96e56f685a7f1f0a19e7ccee5 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:56:32 +0700 Subject: [PATCH 069/312] test --- test/MaglevEulerSwapFactoryTest.t.sol | 58 +++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 test/MaglevEulerSwapFactoryTest.t.sol diff --git a/test/MaglevEulerSwapFactoryTest.t.sol b/test/MaglevEulerSwapFactoryTest.t.sol new file mode 100644 index 0000000..01e137c --- /dev/null +++ b/test/MaglevEulerSwapFactoryTest.t.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; + +// import {Test, console} from "forge-std/Test.sol"; +// import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; +// import {IEVault} from "evk/EVault/IEVault.sol"; +import {MaglevTestBase} from "./MaglevTestBase.t.sol"; +import {MaglevEulerSwap as Maglev} from "../src/MaglevEulerSwap.sol"; +import {MaglevEulerSwapFactory} from "../src/MaglevEulerSwapFactory.sol"; + +contract MaglevEulerSwapFactoryTest is MaglevTestBase { + MaglevEulerSwapFactory public eulerSwapFactory; + + uint256 minFee = 0.0000000000001e18; + + function setUp() public virtual override { + super.setUp(); + + vm.prank(creator); + eulerSwapFactory = new MaglevEulerSwapFactory(address(evc)); + } + + function testDeployPool() public { + uint256 allPoolsLengthBefore = eulerSwapFactory.allPoolsLength(); + + vm.prank(creator); + Maglev maglev = Maglev( + eulerSwapFactory.deployPool( + address(eTST), address(eTST2), holder, 50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18 + ) + ); + + uint256 allPoolsLengthAfter = eulerSwapFactory.allPoolsLength(); + + assertEq(allPoolsLengthAfter - allPoolsLengthBefore, 1); + assertEq(eulerSwapFactory.getPool(maglev.asset0(), maglev.asset1(), maglev.feeMultiplier()), address(maglev)); + assertEq(eulerSwapFactory.getPool(maglev.asset1(), maglev.asset0(), maglev.feeMultiplier()), address(maglev)); + + address[] memory poolsList = eulerSwapFactory.getAllPoolsListSlice(0, type(uint256).max); + assertEq(poolsList.length, 1); + assertEq(poolsList[0], address(maglev)); + assertEq(eulerSwapFactory.allPools(0), address(maglev)); + } + + function testDeployPoolWhenAldreadyRegistered() public { + vm.prank(creator); + eulerSwapFactory.deployPool(address(eTST), address(eTST2), holder, 50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + + vm.prank(creator); + vm.expectRevert(MaglevEulerSwapFactory.PoolAlreadyDeployed.selector); + eulerSwapFactory.deployPool(address(eTST), address(eTST2), holder, 50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + } + + function testInvalidGetAllPoolsListSliceQuery() public { + vm.expectRevert(MaglevEulerSwapFactory.InvalidQuery.selector); + eulerSwapFactory.getAllPoolsListSlice(1, 0); + } +} From ade9485c90c95f87c1f64c59130eb270d9fab2c5 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:58:52 +0700 Subject: [PATCH 070/312] typo --- src/MaglevEulerSwapFactory.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MaglevEulerSwapFactory.sol b/src/MaglevEulerSwapFactory.sol index 61b3b06..a6cd1c2 100644 --- a/src/MaglevEulerSwapFactory.sol +++ b/src/MaglevEulerSwapFactory.sol @@ -78,10 +78,10 @@ contract MaglevEulerSwapFactory is Ownable { return allPools.length; } - /// @notice Get a slice of the registered pools array. + /// @notice Get a slice of the deployed pools array. /// @param _start Start index of the slice. /// @param _end End index of the slice. - /// @return An array containing the slice of the registered pools. + /// @return An array containing the slice of the deployed pools. function getAllPoolsListSlice(uint256 _start, uint256 _end) external view returns (address[] memory) { uint256 length = allPools.length; if (_end == type(uint256).max) _end = length; From 40391c5a3ba453234844218ac7aca51807c66ada Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 19 Dec 2024 13:04:50 +0700 Subject: [PATCH 071/312] add tests --- test/MaglevEulerSwapFactoryTest.t.sol | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test/MaglevEulerSwapFactoryTest.t.sol b/test/MaglevEulerSwapFactoryTest.t.sol index 01e137c..2d3c0a0 100644 --- a/test/MaglevEulerSwapFactoryTest.t.sol +++ b/test/MaglevEulerSwapFactoryTest.t.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.24; // import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; // import {IEVault} from "evk/EVault/IEVault.sol"; import {MaglevTestBase} from "./MaglevTestBase.t.sol"; -import {MaglevEulerSwap as Maglev} from "../src/MaglevEulerSwap.sol"; +import {MaglevEulerSwap as Maglev, MaglevBase} from "../src/MaglevEulerSwap.sol"; import {MaglevEulerSwapFactory} from "../src/MaglevEulerSwapFactory.sol"; contract MaglevEulerSwapFactoryTest is MaglevTestBase { @@ -55,4 +55,18 @@ contract MaglevEulerSwapFactoryTest is MaglevTestBase { vm.expectRevert(MaglevEulerSwapFactory.InvalidQuery.selector); eulerSwapFactory.getAllPoolsListSlice(1, 0); } + + function testDeployWithUnsupportedPair() public { + vm.prank(creator); + vm.expectRevert(MaglevBase.UnsupportedPair.selector); + eulerSwapFactory.deployPool(address(eTST), address(eTST), holder, 50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + } + + function testDeployWithBadFee() public { + vm.prank(creator); + vm.expectRevert(MaglevBase.BadFee.selector); + eulerSwapFactory.deployPool( + address(eTST), address(eTST2), holder, 50e18, 50e18, 1e18, 1e18, 1e18, 0.4e18, 0.85e18 + ); + } } From aa0e41813e75869f92dd571d023a4d274899cf34 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Fri, 20 Dec 2024 11:21:52 +0700 Subject: [PATCH 072/312] add getReserves() --- src/MaglevBase.sol | 10 +++++++--- src/interfaces/IMaglevBase.sol | 3 +-- test/ConstantSum.t.sol | 35 ++++++++++++++++++++++------------ test/MaglevTestBase.t.sol | 6 ++++-- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index f799be8..0db73d3 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -17,9 +17,9 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { uint112 public immutable debtLimit1; uint256 public immutable feeMultiplier; - uint112 public reserve0; - uint112 public reserve1; - uint32 public locked; + uint112 internal reserve0; + uint112 internal reserve1; + uint32 internal locked; // uses single storage slot, accessible via getReserves error Locked(); error Overflow(); @@ -116,6 +116,10 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { } } + function getReserves() public view returns (uint112, uint112, uint32) { + return (reserve0, reserve1, locked); + } + function quoteExactInput(address tokenIn, address tokenOut, uint256 amountIn) external view returns (uint256) { return _computeQuote(tokenIn, tokenOut, amountIn, true); } diff --git a/src/interfaces/IMaglevBase.sol b/src/interfaces/IMaglevBase.sol index 0bc4dcc..ce72eb9 100644 --- a/src/interfaces/IMaglevBase.sol +++ b/src/interfaces/IMaglevBase.sol @@ -15,6 +15,5 @@ interface IMaglevBase { function debtLimit0() external view returns (uint112); function debtLimit1() external view returns (uint112); function feeMultiplier() external view returns (uint256); - function reserve0() external view returns (uint112); - function reserve1() external view returns (uint112); + function getReserves() external view returns (uint112, uint112, uint32); } diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index 02f145a..78f3cdd 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -58,8 +58,9 @@ contract ConstantSumTest is MaglevTestBase { } function test_reserveLimit() public monotonicHolderNAV { - assertEq(maglev.reserve0(), 60e18); - assertEq(maglev.reserve1(), 60e18); + (uint112 reserve0, uint112 reserve1,) = maglev.getReserves(); + assertEq(reserve0, 60e18); + assertEq(reserve1, 60e18); assetTST.mint(address(this), 1000e18); @@ -80,38 +81,48 @@ contract ConstantSumTest is MaglevTestBase { maglev.swap(0, amount, address(this), ""); } + (reserve0, reserve1,) = maglev.getReserves(); + assertEq(eTST.balanceOf(holder), 70e18); assertEq(eTST2.debtOf(holder), 50e18); - assertEq(maglev.reserve0(), 120e18); - assertEq(maglev.reserve1(), 0e18); + assertEq(reserve0, 120e18); + assertEq(reserve1, 0e18); // Same debt limit means reserves not affected createMaglev(50e18, 50e18, 0, 1, 1); - assertEq(maglev.reserve0(), 120e18); - assertEq(maglev.reserve1(), 0e18); + (reserve0, reserve1,) = maglev.getReserves(); + + assertEq(reserve0, 120e18); + assertEq(reserve1, 0e18); // Increase debt limit on one side createMaglev(50e18, 55e18, 0, 1, 1); - assertEq(maglev.reserve0(), 120e18); - assertEq(maglev.reserve1(), 5e18); + (reserve0, reserve1,) = maglev.getReserves(); + + assertEq(reserve0, 120e18); + assertEq(reserve1, 5e18); // And the other createMaglev(55e18, 55e18, 0, 1, 1); - assertEq(maglev.reserve0(), 125e18); - assertEq(maglev.reserve1(), 5e18); + (reserve0, reserve1,) = maglev.getReserves(); + + assertEq(reserve0, 125e18); + assertEq(reserve1, 5e18); // Shrink debt limit createMaglev(40e18, 45e18, 0, 1, 1); - assertEq(maglev.reserve0(), 110e18); - assertEq(maglev.reserve1(), 0e18); // can't go below 0 + (reserve0, reserve1,) = maglev.getReserves(); + + assertEq(reserve0, 110e18); + assertEq(reserve1, 0e18); // can't go below 0 } function test_basicSwapFuzz(uint256 amount1, uint256 amount2) public monotonicHolderNAV { diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index eb28099..b767a5d 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -91,6 +91,8 @@ contract MaglevTestBase is EVaultTestBase { } function logState(address ml) internal view { + (uint112 reserve0, uint112 reserve1,) = MaglevBase(ml).getReserves(); + console.log("--------------------"); console.log("Account States:"); console.log("HOLDER"); @@ -98,7 +100,7 @@ contract MaglevTestBase is EVaultTestBase { console.log(" eTST Vault debt: ", eTST.debtOf(holder)); console.log(" eTST2 Vault assets: ", eTST2.convertToAssets(eTST2.balanceOf(holder))); console.log(" eTST2 Vault debt: ", eTST2.debtOf(holder)); - console.log(" reserve0: ", MaglevBase(ml).reserve0()); - console.log(" reserve1: ", MaglevBase(ml).reserve1()); + console.log(" reserve0: ", reserve0); + console.log(" reserve1: ", reserve1); } } From 75574fadbdefb650f1914e8bf4ae54ba55a42275 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Fri, 20 Dec 2024 11:33:46 +0700 Subject: [PATCH 073/312] typo --- src/MaglevBase.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 0db73d3..2357348 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -19,7 +19,7 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { uint112 internal reserve0; uint112 internal reserve1; - uint32 internal locked; // uses single storage slot, accessible via getReserves + uint32 internal locked; // uses single storage slot, accessible via getReserves() error Locked(); error Overflow(); From 94e072d010a931cc91743e61e7d2947ea0d4707b Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:54:22 +0700 Subject: [PATCH 074/312] add interface --- src/MaglevEulerSwapFactory.sol | 3 ++- src/interfaces/IMaglevEulerSwapFactory.sol | 23 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/interfaces/IMaglevEulerSwapFactory.sol diff --git a/src/MaglevEulerSwapFactory.sol b/src/MaglevEulerSwapFactory.sol index a6cd1c2..5f647b8 100644 --- a/src/MaglevEulerSwapFactory.sol +++ b/src/MaglevEulerSwapFactory.sol @@ -1,13 +1,14 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; +import {IMaglevEulerSwapFactory} from "./interfaces/IMaglevEulerSwapFactory.sol"; import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; import {MaglevEulerSwap as Maglev, MaglevBase} from "./MaglevEulerSwap.sol"; /// @title MaglevEulerSwapRegistry contract /// @custom:security-contact security@euler.xyz /// @author Euler Labs (https://www.eulerlabs.com/) -contract MaglevEulerSwapFactory is Ownable { +contract MaglevEulerSwapFactory is IMaglevEulerSwapFactory, Ownable { event PoolDeployed(address indexed asset0, address indexed asset1, uint256 indexed feeMultiplier, address pool); error InvalidQuery(); diff --git a/src/interfaces/IMaglevEulerSwapFactory.sol b/src/interfaces/IMaglevEulerSwapFactory.sol new file mode 100644 index 0000000..4978e5d --- /dev/null +++ b/src/interfaces/IMaglevEulerSwapFactory.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +interface IMaglevEulerSwapFactory { + function deployPool( + address vault0, + address vault1, + address holder, + uint112 debtLimit0, + uint112 debtLimit1, + uint256 fee, + uint256 priceX, + uint256 priceY, + uint256 concentrationX, + uint256 concentrationY + ) external returns (address); + + function evc() external view returns (address); + function allPools(uint256 index) external view returns (address); + function getPool(address assetA, address assetB, uint256 fee) external view returns (address); + function allPoolsLength() external view returns (uint256); + function getAllPoolsListSlice(uint256 start, uint256 end) external view returns (address[] memory); +} From 0e984f1af9385b9b2d6b9b4589050ee95d657afc Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 20 Dec 2024 16:01:45 -0500 Subject: [PATCH 075/312] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e54e69f..49a6c73 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ At this point, anyone can invoke `swap()` on the Maglev contract, and this will ### Reconfiguration -All user-configurable parameters are stored in immutable variables, meaning they cannot be changed after the AMM is deployed. Instead, the holder should uninstalled it from its EVC operator set, and a new Maglev instance should be created and installed in its place. +All user-configurable parameters are stored in immutable variables, meaning they cannot be changed after the AMM is deployed. Instead, the holder should uninstall it from its EVC operator set, and a new Maglev instance should be created and installed in its place. ### Debt Limits From cc0bfcfc17984b6547d4f9756e66670b831cb0d8 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 20 Dec 2024 16:10:00 -0500 Subject: [PATCH 076/312] todo items --- TODO | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/TODO b/TODO index a6cb01e..bdd7da9 100644 --- a/TODO +++ b/TODO @@ -2,9 +2,16 @@ * reserve change on each swap ! Better revert messages when a swap cannot be satisifed due to debt-limit/utilisation/etc * currently it's an arithmetic underflow +! Don't make quotes that would cause a swap to fail due to supply or borrow caps +! Use `myDebt() == 0` condition for disabling controller: more accurate +! In _computeQuote() use vault.cash() method instead of token.balanceOf() otherwise donations could cause quoted swaps to fail +! In _computeQuote(), exactOut swaps should verify the *amount* (not quote) is withdrawable * ConstantSum: incorporate price multipliers in quote methods * natspec * permit2 instead of regular approval: measure gas savings +* in constructor, check the two vaults have the correct EVC() return value + * maybe even that they were created by the EVK factory? +? a really small swap could fail because deposit() results in 0 shares, which EVK fails on. call convertToShares() first? Seems like overkill ? pause guardian ? how should aggregators find instances ? factory/registry contract From 757af4bf716eb8497dcc406a30c44f086f91c26a Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 Jan 2025 17:34:42 +0700 Subject: [PATCH 077/312] Use myDebt() to check debt amount before disabling controller --- src/MaglevBase.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 2357348..af70b10 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -178,7 +178,7 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { vault, myAccount, 0, abi.encodeCall(IBorrowing.repayWithShares, (type(uint256).max, myAccount)) ); - if (debt <= amount) { + if (myDebt(vault) == 0) { IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IRiskManager.disableController, ())); } } From 1ddc9a68b7c826688afcb6b59e3d6e592a699059 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 Jan 2025 17:35:23 +0700 Subject: [PATCH 078/312] clean ToDo list --- TODO | 1 - 1 file changed, 1 deletion(-) diff --git a/TODO b/TODO index bdd7da9..3203a03 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,6 @@ ! Better revert messages when a swap cannot be satisifed due to debt-limit/utilisation/etc * currently it's an arithmetic underflow ! Don't make quotes that would cause a swap to fail due to supply or borrow caps -! Use `myDebt() == 0` condition for disabling controller: more accurate ! In _computeQuote() use vault.cash() method instead of token.balanceOf() otherwise donations could cause quoted swaps to fail ! In _computeQuote(), exactOut swaps should verify the *amount* (not quote) is withdrawable * ConstantSum: incorporate price multipliers in quote methods From f980ee91328261b513aa5df3cbb8ff3cceada55d Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 Jan 2025 18:03:59 +0700 Subject: [PATCH 079/312] use .cash() --- TODO | 1 - src/MaglevBase.sol | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/TODO b/TODO index bdd7da9..a135ca8 100644 --- a/TODO +++ b/TODO @@ -4,7 +4,6 @@ * currently it's an arithmetic underflow ! Don't make quotes that would cause a swap to fail due to supply or borrow caps ! Use `myDebt() == 0` condition for disabling controller: more accurate -! In _computeQuote() use vault.cash() method instead of token.balanceOf() otherwise donations could cause quoted swaps to fail ! In _computeQuote(), exactOut swaps should verify the *amount* (not quote) is withdrawable * ConstantSum: incorporate price multipliers in quote methods * natspec diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 2357348..4f59ff8 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -200,10 +200,7 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { uint256 quote = computeQuote(amount, exactIn, asset0IsInput); require(quote <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); - require( - quote <= IERC20(asset0IsInput ? asset1 : asset0).balanceOf(asset0IsInput ? vault1 : vault0), - InsufficientCash() - ); + require(quote <= IEVault(asset0IsInput ? vault1 : vault0).cash(), InsufficientCash()); // exactOut: increase required amountIn, rounding up if (!exactIn) quote = (quote * 1e18 + (feeMultiplier - 1)) / feeMultiplier; From b093fe2087907d6c106809642d71e453dcc35891 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 Jan 2025 18:24:18 +0700 Subject: [PATCH 080/312] fix _computeQuote --- src/MaglevBase.sol | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 4f59ff8..c2cda61 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -199,10 +199,17 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { uint256 quote = computeQuote(amount, exactIn, asset0IsInput); - require(quote <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); - require(quote <= IEVault(asset0IsInput ? vault1 : vault0).cash(), InsufficientCash()); + if (exactIn) { + // if `exactIn`, `quote` is the amount of assets to buy from the AMM + require(quote <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); + require(quote <= IEVault(asset0IsInput ? vault1 : vault0).cash(), InsufficientCash()); + } else { + // if `!exactIn`, `amount` is the amount of assets to buy from the AMM + require(amount <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); + require(amount <= IEVault(asset0IsInput ? vault1 : vault0).cash(), InsufficientCash()); + } - // exactOut: increase required amountIn, rounding up + // exactOut: increase required quote(amountIn), rounding up if (!exactIn) quote = (quote * 1e18 + (feeMultiplier - 1)) / feeMultiplier; return quote; From 593a38f3457e487993ddee410514528c2bc0ce5a Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 Jan 2025 18:25:25 +0700 Subject: [PATCH 081/312] clean ToDo list --- TODO | 1 - 1 file changed, 1 deletion(-) diff --git a/TODO b/TODO index a135ca8..65e08c6 100644 --- a/TODO +++ b/TODO @@ -4,7 +4,6 @@ * currently it's an arithmetic underflow ! Don't make quotes that would cause a swap to fail due to supply or borrow caps ! Use `myDebt() == 0` condition for disabling controller: more accurate -! In _computeQuote(), exactOut swaps should verify the *amount* (not quote) is withdrawable * ConstantSum: incorporate price multipliers in quote methods * natspec * permit2 instead of regular approval: measure gas savings From 5c941d466029f0c6e544d78ae869197f78826331 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 Jan 2025 19:09:30 +0700 Subject: [PATCH 082/312] check that all used EVC addresses are the same --- TODO | 2 -- src/MaglevBase.sol | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index bdd7da9..1375f26 100644 --- a/TODO +++ b/TODO @@ -9,8 +9,6 @@ * ConstantSum: incorporate price multipliers in quote methods * natspec * permit2 instead of regular approval: measure gas savings -* in constructor, check the two vaults have the correct EVC() return value - * maybe even that they were created by the EVK factory? ? a really small swap could fail because deposit() results in 0 shares, which EVK fails on. call convertToShares() first? Seems like overkill ? pause guardian ? how should aggregators find instances diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 2357348..9091ef1 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -27,6 +27,7 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { error BadFee(); error InsufficientReserves(); error InsufficientCash(); + error DifferentEVC(); modifier nonReentrant() { require(locked == 0, Locked()); @@ -48,6 +49,10 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { constructor(BaseParams memory params) EVCUtil(params.evc) { require(params.fee < 1e18, BadFee()); + address vault0Evc = IEVault(params.vault0).EVC(); + require(vault0Evc == IEVault(params.vault1).EVC(), DifferentEVC()); + require(vault0Evc == params.evc, DifferentEVC()); + vault0 = params.vault0; vault1 = params.vault1; asset0 = IEVault(vault0).asset(); From 26e28eb95027dd653658437819949bb7a39149f8 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 Jan 2025 19:45:11 +0700 Subject: [PATCH 083/312] test --- test/EulerSwap.t.sol | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 2e81b00..c5c3b18 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -8,7 +8,7 @@ import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; import {MaglevTestBase} from "./MaglevTestBase.t.sol"; -import {MaglevEulerSwap as Maglev} from "../src/MaglevEulerSwap.sol"; +import {MaglevEulerSwap as Maglev, MaglevBase} from "../src/MaglevEulerSwap.sol"; contract EulerSwapTest is MaglevTestBase { Maglev public maglev; @@ -41,6 +41,23 @@ contract EulerSwapTest is MaglevTestBase { maglev.configure(); } + function test_different_EVC() public { + vm.expectRevert(MaglevBase.DifferentEVC.selector); + + new Maglev( + MaglevBase.BaseParams({ + evc: address(makeAddr("RANDOM_EVC")), + vault0: address(eTST), + vault1: address(eTST2), + myAccount: holder, + debtLimit0: 50e18, + debtLimit1: 50e18, + fee: 0 + }), + Maglev.EulerSwapParams({priceX: 1e18, priceY: 1e18, concentrationX: 4e18, concentrationY: 0.85e18}) + ); + } + function test_basicSwap_exactIn() public monotonicHolderNAV { uint256 amountIn = 1e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); From d14c30c97e36ec9852ab7f159522cab3f55dd4f1 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 Jan 2025 20:35:49 +0700 Subject: [PATCH 084/312] init events --- src/MaglevBase.sol | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 2357348..c252e71 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -45,6 +45,17 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { uint256 fee; } + event Swap( + address indexed sender, + uint256 amount0In, + uint256 amount1In, + uint256 amount0Out, + uint256 amount1Out, + uint112 reserve0, + uint112 reserve1, + address indexed to + ); + constructor(BaseParams memory params) EVCUtil(params.evc) { require(params.fee < 1e18, BadFee()); @@ -113,6 +124,10 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { reserve0 = uint112(newReserve0); reserve1 = uint112(newReserve1); + + emit Swap( + msg.sender, amount0In, amount1In, amount0Out, amount1Out, uint112(newReserve0), uint112(newReserve1), to + ); } } From c58f868351adc0f8d1aba9d33b7fd3f1b4e78efa Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Tue, 14 Jan 2025 23:53:38 +0700 Subject: [PATCH 085/312] fix-ci: ignore test file during build --sizes --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 762a296..bd898e6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,7 +36,7 @@ jobs: - name: Run Forge build run: | - forge build --sizes + forge build --force --skip test --sizes id: build - name: Run Forge tests From 32ddf9d2c37bd4a07fc35f7d24618e808675363e Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Tue, 14 Jan 2025 23:53:50 +0700 Subject: [PATCH 086/312] fix: asset0 and asset1 order --- src/MaglevBase.sol | 42 ++++++++++++++++++++++++-------------- test/ConstantProduct.t.sol | 4 ++-- test/ConstantSum.t.sol | 4 ++-- test/EulerSwap.t.sol | 14 ++++++------- test/MaglevTestBase.t.sol | 10 ++++----- test/UniswapV2Call.t.sol | 6 +++--- 6 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 17060f0..8d243ca 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -38,11 +38,11 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { struct BaseParams { address evc; - address vault0; - address vault1; + address vaultA; + address vaultB; address myAccount; - uint112 debtLimit0; - uint112 debtLimit1; + uint112 debtLimitA; + uint112 debtLimitB; uint256 fee; } @@ -60,20 +60,32 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { constructor(BaseParams memory params) EVCUtil(params.evc) { require(params.fee < 1e18, BadFee()); - address vault0Evc = IEVault(params.vault0).EVC(); - require(vault0Evc == IEVault(params.vault1).EVC(), DifferentEVC()); - require(vault0Evc == params.evc, DifferentEVC()); + address vaultAEvc = IEVault(params.vaultA).EVC(); + require(vaultAEvc == IEVault(params.vaultB).EVC(), DifferentEVC()); + require(vaultAEvc == params.evc, DifferentEVC()); - vault0 = params.vault0; - vault1 = params.vault1; - asset0 = IEVault(vault0).asset(); - asset1 = IEVault(vault1).asset(); - - require(asset0 != asset1, UnsupportedPair()); + address assetA = IEVault(params.vaultA).asset(); + address assetB = IEVault(params.vaultB).asset(); + require(assetA != assetB, UnsupportedPair()); myAccount = params.myAccount; - reserve0 = offsetReserve(params.debtLimit0, vault0); - reserve1 = offsetReserve(params.debtLimit1, vault1); + (vault0, asset0, reserve0, vault1, asset1, reserve1) = assetA < assetB + ? ( + params.vaultA, + assetA, + offsetReserve(params.debtLimitA, params.vaultA), + params.vaultB, + assetB, + offsetReserve(params.debtLimitB, params.vaultB) + ) + : ( + params.vaultB, + assetB, + offsetReserve(params.debtLimitB, params.vaultB), + params.vaultA, + assetA, + offsetReserve(params.debtLimitA, params.vaultA) + ); feeMultiplier = 1e18 - params.fee; } diff --git a/test/ConstantProduct.t.sol b/test/ConstantProduct.t.sol index 47a8fbe..b3d1e4d 100644 --- a/test/ConstantProduct.t.sol +++ b/test/ConstantProduct.t.sol @@ -19,9 +19,9 @@ contract ConstantProductTest is MaglevTestBase { createMaglev(50e18, 50e18, 0); } - function createMaglev(uint112 debtLimit0, uint112 debtLimit1, uint256 fee) internal { + function createMaglev(uint112 debtLimitA, uint112 debtLimitB, uint256 fee) internal { vm.prank(creator); - maglev = new Maglev(getMaglevBaseParams(debtLimit0, debtLimit1, fee)); + maglev = new Maglev(getMaglevBaseParams(debtLimitA, debtLimitB, fee)); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index 78f3cdd..7d1a805 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -19,12 +19,12 @@ contract ConstantSumTest is MaglevTestBase { createMaglev(50e18, 50e18, 0, 1, 1); } - function createMaglev(uint112 debtLimit0, uint112 debtLimit1, uint256 fee, uint256 priceX, uint256 priceY) + function createMaglev(uint112 debtLimitA, uint112 debtLimitB, uint256 fee, uint256 priceX, uint256 priceY) internal { vm.prank(creator); maglev = new Maglev( - getMaglevBaseParams(debtLimit0, debtLimit1, fee), Maglev.ConstantSumParams({priceX: priceX, priceY: priceY}) + getMaglevBaseParams(debtLimitA, debtLimitB, fee), Maglev.ConstantSumParams({priceX: priceX, priceY: priceY}) ); vm.prank(holder); diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index c5c3b18..4b91156 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -20,8 +20,8 @@ contract EulerSwapTest is MaglevTestBase { } function createMaglev( - uint112 debtLimit0, - uint112 debtLimit1, + uint112 debtLimitA, + uint112 debtLimitB, uint256 fee, uint256 px, uint256 py, @@ -30,7 +30,7 @@ contract EulerSwapTest is MaglevTestBase { ) internal { vm.prank(creator); maglev = new Maglev( - getMaglevBaseParams(debtLimit0, debtLimit1, fee), + getMaglevBaseParams(debtLimitA, debtLimitB, fee), Maglev.EulerSwapParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) ); @@ -47,11 +47,11 @@ contract EulerSwapTest is MaglevTestBase { new Maglev( MaglevBase.BaseParams({ evc: address(makeAddr("RANDOM_EVC")), - vault0: address(eTST), - vault1: address(eTST2), + vaultA: address(eTST), + vaultB: address(eTST2), myAccount: holder, - debtLimit0: 50e18, - debtLimit1: 50e18, + debtLimitA: 50e18, + debtLimitB: 50e18, fee: 0 }), Maglev.EulerSwapParams({priceX: 1e18, priceY: 1e18, concentrationX: 4e18, concentrationY: 0.85e18}) diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index b767a5d..cfed3ea 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -43,18 +43,18 @@ contract MaglevTestBase is EVaultTestBase { _mintAndDeposit(holder, eTST2, 10e18); } - function getMaglevBaseParams(uint112 debtLimit0, uint112 debtLimit1, uint256 fee) + function getMaglevBaseParams(uint112 debtLimitA, uint112 debtLimitB, uint256 fee) internal view returns (MaglevBase.BaseParams memory) { return MaglevBase.BaseParams({ evc: address(evc), - vault0: address(eTST), - vault1: address(eTST2), + vaultA: address(eTST), + vaultB: address(eTST2), myAccount: holder, - debtLimit0: debtLimit0, - debtLimit1: debtLimit1, + debtLimitA: debtLimitA, + debtLimitB: debtLimitB, fee: fee }); } diff --git a/test/UniswapV2Call.t.sol b/test/UniswapV2Call.t.sol index 11516d3..66f9a8b 100644 --- a/test/UniswapV2Call.t.sol +++ b/test/UniswapV2Call.t.sol @@ -19,8 +19,8 @@ contract UniswapV2CallTest is MaglevTestBase { } function createMaglev( - uint112 debtLimit0, - uint112 debtLimit1, + uint112 debtLimitA, + uint112 debtLimitB, uint256 fee, uint256 px, uint256 py, @@ -29,7 +29,7 @@ contract UniswapV2CallTest is MaglevTestBase { ) internal { vm.prank(creator); maglev = new Maglev( - getMaglevBaseParams(debtLimit0, debtLimit1, fee), + getMaglevBaseParams(debtLimitA, debtLimitB, fee), Maglev.EulerSwapParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) ); From 6e43da3b67d41c0f98fd172c878f05b2938764d6 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Tue, 14 Jan 2025 23:59:43 +0700 Subject: [PATCH 087/312] clean --- src/MaglevBase.sol | 2 -- src/interfaces/IMaglevBase.sol | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 8d243ca..b535dab 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -13,8 +13,6 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { address public immutable asset0; address public immutable asset1; address public immutable myAccount; - uint112 public immutable debtLimit0; - uint112 public immutable debtLimit1; uint256 public immutable feeMultiplier; uint112 internal reserve0; diff --git a/src/interfaces/IMaglevBase.sol b/src/interfaces/IMaglevBase.sol index ce72eb9..242ca74 100644 --- a/src/interfaces/IMaglevBase.sol +++ b/src/interfaces/IMaglevBase.sol @@ -12,8 +12,6 @@ interface IMaglevBase { function asset0() external view returns (address); function asset1() external view returns (address); function myAccount() external view returns (address); - function debtLimit0() external view returns (uint112); - function debtLimit1() external view returns (uint112); function feeMultiplier() external view returns (uint256); function getReserves() external view returns (uint112, uint112, uint32); } From e69004a97a26031be200cc44fab9ade35290a470 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 15 Jan 2025 15:59:35 +0700 Subject: [PATCH 088/312] feat: allow re-deploying pool with same asset0/asset1/fee --- src/MaglevEulerSwapFactory.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/MaglevEulerSwapFactory.sol b/src/MaglevEulerSwapFactory.sol index 5f647b8..0f1906c 100644 --- a/src/MaglevEulerSwapFactory.sol +++ b/src/MaglevEulerSwapFactory.sol @@ -60,8 +60,6 @@ contract MaglevEulerSwapFactory is IMaglevEulerSwapFactory, Ownable { address poolAsset1 = pool.asset1(); uint256 feeMultiplier = pool.feeMultiplier(); - require(getPool[poolAsset0][poolAsset1][feeMultiplier] == address(0), PoolAlreadyDeployed()); - getPool[poolAsset0][poolAsset1][feeMultiplier] = address(pool); // populate mapping in the reverse direction, deliberate choice to avoid the cost of comparing addresses getPool[poolAsset1][poolAsset0][feeMultiplier] = address(pool); From db650f3d1169e98eab5580f70245e2cdeee99d45 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 15 Jan 2025 16:00:07 +0700 Subject: [PATCH 089/312] clean' --- src/MaglevEulerSwapFactory.sol | 1 - test/MaglevEulerSwapFactoryTest.t.sol | 9 --------- 2 files changed, 10 deletions(-) diff --git a/src/MaglevEulerSwapFactory.sol b/src/MaglevEulerSwapFactory.sol index 0f1906c..a9ce3c5 100644 --- a/src/MaglevEulerSwapFactory.sol +++ b/src/MaglevEulerSwapFactory.sol @@ -12,7 +12,6 @@ contract MaglevEulerSwapFactory is IMaglevEulerSwapFactory, Ownable { event PoolDeployed(address indexed asset0, address indexed asset1, uint256 indexed feeMultiplier, address pool); error InvalidQuery(); - error PoolAlreadyDeployed(); /// @dev EVC address. address public immutable evc; diff --git a/test/MaglevEulerSwapFactoryTest.t.sol b/test/MaglevEulerSwapFactoryTest.t.sol index 2d3c0a0..3f5df30 100644 --- a/test/MaglevEulerSwapFactoryTest.t.sol +++ b/test/MaglevEulerSwapFactoryTest.t.sol @@ -42,15 +42,6 @@ contract MaglevEulerSwapFactoryTest is MaglevTestBase { assertEq(eulerSwapFactory.allPools(0), address(maglev)); } - function testDeployPoolWhenAldreadyRegistered() public { - vm.prank(creator); - eulerSwapFactory.deployPool(address(eTST), address(eTST2), holder, 50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); - - vm.prank(creator); - vm.expectRevert(MaglevEulerSwapFactory.PoolAlreadyDeployed.selector); - eulerSwapFactory.deployPool(address(eTST), address(eTST2), holder, 50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); - } - function testInvalidGetAllPoolsListSliceQuery() public { vm.expectRevert(MaglevEulerSwapFactory.InvalidQuery.selector); eulerSwapFactory.getAllPoolsListSlice(1, 0); From 69245d03b9f68530b8bfa1045e6293acbdd94226 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Fri, 24 Jan 2025 16:08:21 +0700 Subject: [PATCH 090/312] update factory --- foundry.toml | 3 +++ src/MaglevEulerSwapFactory.sol | 21 ++++++++++++++------- src/interfaces/IMaglevEulerSwapFactory.sol | 8 ++++---- test/MaglevEulerSwapFactoryTest.t.sol | 22 +++++++++++++++++----- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/foundry.toml b/foundry.toml index fc855a1..d8142ba 100644 --- a/foundry.toml +++ b/foundry.toml @@ -3,5 +3,8 @@ src = "src" out = "out" libs = ["lib"] solc = "0.8.27" +optimizer = true +optimizer_runs = 800 +gas_reports = ["*"] # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/src/MaglevEulerSwapFactory.sol b/src/MaglevEulerSwapFactory.sol index a9ce3c5..e92b3b5 100644 --- a/src/MaglevEulerSwapFactory.sol +++ b/src/MaglevEulerSwapFactory.sol @@ -18,7 +18,7 @@ contract MaglevEulerSwapFactory is IMaglevEulerSwapFactory, Ownable { /// @dev An array to store all pools addresses. address[] public allPools; /// @dev Mapping from asset0/asset1/fee => pool address. - mapping(address => mapping(address => mapping(uint256 => address))) public getPool; + mapping(bytes32 => address) public getPool; constructor(address evcAddr) Ownable(msg.sender) { evc = evcAddr; @@ -29,13 +29,13 @@ contract MaglevEulerSwapFactory is IMaglevEulerSwapFactory, Ownable { address vault0, address vault1, address holder, - uint112 debtLimit0, - uint112 debtLimit1, uint256 fee, uint256 priceX, uint256 priceY, uint256 concentrationX, - uint256 concentrationY + uint256 concentrationY, + uint112 debtLimit0, + uint112 debtLimit1 ) external onlyOwner returns (address) { Maglev pool = new Maglev( MaglevBase.BaseParams({ @@ -58,11 +58,18 @@ contract MaglevEulerSwapFactory is IMaglevEulerSwapFactory, Ownable { address poolAsset0 = pool.asset0(); address poolAsset1 = pool.asset1(); uint256 feeMultiplier = pool.feeMultiplier(); + address myAccount = pool.myAccount(); + uint256 priceX = pool.priceX(); + uint256 priceY = pool.priceY(); + uint256 concentrationX = pool.concentrationX(); + uint256 concentrationY = pool.concentrationY(); - getPool[poolAsset0][poolAsset1][feeMultiplier] = address(pool); - // populate mapping in the reverse direction, deliberate choice to avoid the cost of comparing addresses - getPool[poolAsset1][poolAsset0][feeMultiplier] = address(pool); + bytes32 poolKey = keccak256( + abi.encode(poolAsset0, poolAsset1, feeMultiplier, myAccount, priceX, priceY, concentrationX, concentrationY) + ); + + getPool[poolKey] = address(pool); allPools.push(address(pool)); emit PoolDeployed(poolAsset0, poolAsset1, feeMultiplier, address(pool)); diff --git a/src/interfaces/IMaglevEulerSwapFactory.sol b/src/interfaces/IMaglevEulerSwapFactory.sol index 4978e5d..6017c10 100644 --- a/src/interfaces/IMaglevEulerSwapFactory.sol +++ b/src/interfaces/IMaglevEulerSwapFactory.sol @@ -6,18 +6,18 @@ interface IMaglevEulerSwapFactory { address vault0, address vault1, address holder, - uint112 debtLimit0, - uint112 debtLimit1, uint256 fee, uint256 priceX, uint256 priceY, uint256 concentrationX, - uint256 concentrationY + uint256 concentrationY, + uint112 debtLimit0, + uint112 debtLimit1 ) external returns (address); function evc() external view returns (address); function allPools(uint256 index) external view returns (address); - function getPool(address assetA, address assetB, uint256 fee) external view returns (address); + function getPool(bytes32 poolKey) external view returns (address); function allPoolsLength() external view returns (uint256); function getAllPoolsListSlice(uint256 start, uint256 end) external view returns (address[] memory); } diff --git a/test/MaglevEulerSwapFactoryTest.t.sol b/test/MaglevEulerSwapFactoryTest.t.sol index 3f5df30..0ae6f45 100644 --- a/test/MaglevEulerSwapFactoryTest.t.sol +++ b/test/MaglevEulerSwapFactoryTest.t.sol @@ -26,15 +26,27 @@ contract MaglevEulerSwapFactoryTest is MaglevTestBase { vm.prank(creator); Maglev maglev = Maglev( eulerSwapFactory.deployPool( - address(eTST), address(eTST2), holder, 50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18 + address(eTST), address(eTST2), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 ) ); uint256 allPoolsLengthAfter = eulerSwapFactory.allPoolsLength(); + bytes32 poolKey = keccak256( + abi.encode( + maglev.asset0(), + maglev.asset1(), + maglev.feeMultiplier(), + maglev.myAccount(), + maglev.priceX(), + maglev.priceY(), + maglev.concentrationX(), + maglev.concentrationY() + ) + ); assertEq(allPoolsLengthAfter - allPoolsLengthBefore, 1); - assertEq(eulerSwapFactory.getPool(maglev.asset0(), maglev.asset1(), maglev.feeMultiplier()), address(maglev)); - assertEq(eulerSwapFactory.getPool(maglev.asset1(), maglev.asset0(), maglev.feeMultiplier()), address(maglev)); + assertEq(eulerSwapFactory.getPool(poolKey), address(maglev)); + assertEq(eulerSwapFactory.getPool(poolKey), address(maglev)); address[] memory poolsList = eulerSwapFactory.getAllPoolsListSlice(0, type(uint256).max); assertEq(poolsList.length, 1); @@ -50,14 +62,14 @@ contract MaglevEulerSwapFactoryTest is MaglevTestBase { function testDeployWithUnsupportedPair() public { vm.prank(creator); vm.expectRevert(MaglevBase.UnsupportedPair.selector); - eulerSwapFactory.deployPool(address(eTST), address(eTST), holder, 50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + eulerSwapFactory.deployPool(address(eTST), address(eTST), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18); } function testDeployWithBadFee() public { vm.prank(creator); vm.expectRevert(MaglevBase.BadFee.selector); eulerSwapFactory.deployPool( - address(eTST), address(eTST2), holder, 50e18, 50e18, 1e18, 1e18, 1e18, 0.4e18, 0.85e18 + address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 ); } } From 9193f596f9b7c61385e61308a940c3539d1fd4b7 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Fri, 24 Jan 2025 16:08:57 +0700 Subject: [PATCH 091/312] lint --- src/MaglevEulerSwapFactory.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/src/MaglevEulerSwapFactory.sol b/src/MaglevEulerSwapFactory.sol index e92b3b5..b2b1be6 100644 --- a/src/MaglevEulerSwapFactory.sol +++ b/src/MaglevEulerSwapFactory.sol @@ -64,7 +64,6 @@ contract MaglevEulerSwapFactory is IMaglevEulerSwapFactory, Ownable { uint256 concentrationX = pool.concentrationX(); uint256 concentrationY = pool.concentrationY(); - bytes32 poolKey = keccak256( abi.encode(poolAsset0, poolAsset1, feeMultiplier, myAccount, priceX, priceY, concentrationX, concentrationY) ); From 742d4b257e94e5eec67122d8520074e28a99cc93 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 6 Feb 2025 00:09:16 +0800 Subject: [PATCH 092/312] refactor: assets order --- src/MaglevBase.sol | 44 +++++++++++++++------------------------ test/EulerSwap.t.sol | 8 +++---- test/MaglevTestBase.t.sol | 8 +++---- 3 files changed, 25 insertions(+), 35 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index b535dab..cdabe6f 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -26,6 +26,7 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { error InsufficientReserves(); error InsufficientCash(); error DifferentEVC(); + error AssetsOutOfOrderOrEqual(); modifier nonReentrant() { require(locked == 0, Locked()); @@ -36,11 +37,11 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { struct BaseParams { address evc; - address vaultA; - address vaultB; + address vault0; + address vault1; address myAccount; - uint112 debtLimitA; - uint112 debtLimitB; + uint112 debtLimit0; + uint112 debtLimit1; uint256 fee; } @@ -58,32 +59,21 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { constructor(BaseParams memory params) EVCUtil(params.evc) { require(params.fee < 1e18, BadFee()); - address vaultAEvc = IEVault(params.vaultA).EVC(); - require(vaultAEvc == IEVault(params.vaultB).EVC(), DifferentEVC()); - require(vaultAEvc == params.evc, DifferentEVC()); + address vault0Evc = IEVault(params.vault0).EVC(); + require(vault0Evc == IEVault(params.vault1).EVC(), DifferentEVC()); + require(vault0Evc == params.evc, DifferentEVC()); - address assetA = IEVault(params.vaultA).asset(); - address assetB = IEVault(params.vaultB).asset(); - require(assetA != assetB, UnsupportedPair()); + address asset0Addr = IEVault(params.vault0).asset(); + address asset1Addr = IEVault(params.vault1).asset(); + require(asset0Addr < asset1Addr, AssetsOutOfOrderOrEqual()); myAccount = params.myAccount; - (vault0, asset0, reserve0, vault1, asset1, reserve1) = assetA < assetB - ? ( - params.vaultA, - assetA, - offsetReserve(params.debtLimitA, params.vaultA), - params.vaultB, - assetB, - offsetReserve(params.debtLimitB, params.vaultB) - ) - : ( - params.vaultB, - assetB, - offsetReserve(params.debtLimitB, params.vaultB), - params.vaultA, - assetA, - offsetReserve(params.debtLimitA, params.vaultA) - ); + vault0 = params.vault0; + vault1 = params.vault1; + asset0 = asset0Addr; + asset1 = asset1Addr; + reserve0 = offsetReserve(params.debtLimit0, params.vault0); + reserve1 = offsetReserve(params.debtLimit1, params.vault1); feeMultiplier = 1e18 - params.fee; } diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 4b91156..4aa9a2f 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -47,11 +47,11 @@ contract EulerSwapTest is MaglevTestBase { new Maglev( MaglevBase.BaseParams({ evc: address(makeAddr("RANDOM_EVC")), - vaultA: address(eTST), - vaultB: address(eTST2), + vault0: address(eTST), + vault1: address(eTST2), myAccount: holder, - debtLimitA: 50e18, - debtLimitB: 50e18, + debtLimit0: 50e18, + debtLimit1: 50e18, fee: 0 }), Maglev.EulerSwapParams({priceX: 1e18, priceY: 1e18, concentrationX: 4e18, concentrationY: 0.85e18}) diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index cfed3ea..a6112c3 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -50,11 +50,11 @@ contract MaglevTestBase is EVaultTestBase { { return MaglevBase.BaseParams({ evc: address(evc), - vaultA: address(eTST), - vaultB: address(eTST2), + vault0: address(eTST), + vault1: address(eTST2), myAccount: holder, - debtLimitA: debtLimitA, - debtLimitB: debtLimitB, + debtLimit0: debtLimitA, + debtLimit1: debtLimitB, fee: fee }); } From 5048fc6e151761efc0fb149d812215ac8235ebb3 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 7 Feb 2025 22:19:41 -0500 Subject: [PATCH 093/312] quotePadding, add new test --- README.md | 2 +- src/MaglevEulerSwap.sol | 14 ++-- test/EulerSwap.t.sol | 4 +- test/PreserveNav.t.sol | 141 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 10 deletions(-) create mode 100644 test/PreserveNav.t.sol diff --git a/README.md b/README.md index 49a6c73..8b901e4 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ With careful parameter selection, the EulerSwap curve supports optimal tradeoffs * The EulerSwap curve has some numerical instability that we believe is caused by rounding * We think the biggest effect is that it may cause some swaps to fail even if the exact quoted amount is sent. Also, it may result in users slightly overpaying for swaps. - * The code currently has a roundingCompensation adjustment that seems to prevent this, but since we don't know a hard upper-bound it's hard to say if this solves it in all cases + * The code currently has a quotePadding adjustment that seems to prevent this, but since we don't know a hard upper-bound it's hard to say if this solves it in all cases. In particular, this will only work well for 18-decimal tokens of reasonable prices * Currently we have only been supporting stable-stable pairs * What extra considerations would there be for floating pairs? * Automatically re-invest fees. There are a few options: diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index 3d8aa04..b3855a9 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -34,11 +34,6 @@ contract MaglevEulerSwap is IMaglevEulerSwap, MaglevBase { initialReserve1 = reserve1; } - // Due to rounding, computeQuote() may underestimate the amount required to - // pass the verify() function. In order to prevent swaps from failing, quotes - // are inflated by this compensation factor. FIXME: solve the rounding. - uint256 private constant roundingCompensation = 1.0000000000001e18; - function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override { int256 delta = 0; @@ -54,6 +49,11 @@ contract MaglevEulerSwap is IMaglevEulerSwap, MaglevBase { require(delta >= 0, KNotSatisfied()); } + // Due to rounding, computeQuote() may underestimate the amount required to + // pass the verify() function. In order to prevent swaps from failing, quotes + // are inflated by this padding factor. + uint256 private constant quotePadding = 1.00000000001e18; + function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view @@ -112,11 +112,11 @@ contract MaglevEulerSwap is IMaglevEulerSwap, MaglevBase { if (exactIn) { if (asset0IsInput) output = uint256(-dy); else output = uint256(-dx); - output = output * 1e18 / roundingCompensation; + output = output * 1e18 / quotePadding; } else { if (asset0IsInput) output = uint256(dx); else output = uint256(dy); - output = output * roundingCompensation / 1e18; + output = output * quotePadding / 1e18; } } diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 4aa9a2f..893f2f0 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -173,7 +173,7 @@ contract EulerSwapTest is MaglevTestBase { assertGe(getHolderNAV(), origNAV); } - // To reproduce, change roundingCompensation to 1e18 + // To reproduce, change quotePadding to 1e18 function test_roundingFailure() public { uint256 amountIn = 1.4e18; uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); @@ -210,7 +210,7 @@ contract EulerSwapTest is MaglevTestBase { t1.transfer(address(maglev), amount); { - uint256 qPlus = q * 1.0000000000002e18 / 1e18; + uint256 qPlus = q * 1.00000000002e18 / 1e18; vm.expectRevert(); if (dir) maglev.swap(0, qPlus, address(this), ""); else maglev.swap(qPlus, 0, address(this), ""); diff --git a/test/PreserveNav.t.sol b/test/PreserveNav.t.sol new file mode 100644 index 0000000..bbb37b6 --- /dev/null +++ b/test/PreserveNav.t.sol @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.24; + +import {Test, console} from "forge-std/Test.sol"; + +import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; +import {MaglevTestBase} from "./MaglevTestBase.t.sol"; + +import {MaglevEulerSwap as Maglev, MaglevBase} from "../src/MaglevEulerSwap.sol"; + +contract PreserveNav is MaglevTestBase { + Maglev public maglev; + + function setUp() public virtual override { + super.setUp(); + } + + function createMaglev( + uint112 debtLimitA, + uint112 debtLimitB, + uint256 fee, + uint256 px, + uint256 py, + uint256 cx, + uint256 cy + ) internal { + vm.prank(creator); + maglev = new Maglev( + getMaglevBaseParams(debtLimitA, debtLimitB, fee), + Maglev.EulerSwapParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) + ); + + vm.prank(holder); + evc.setAccountOperator(holder, address(maglev), true); + + vm.prank(anyone); + maglev.configure(); + } + + + + function test_preserve_nav(uint256 cx, uint256 cy, uint256 fee, bool preSkimDir, bool dir1, uint256 amount1, bool skimOrder1, bool dir2, uint256 amount2, bool skimOrder2) public { + cx = bound(cx, 0.1e18, 0.99e18); + cy = bound(cy, 0.1e18, 0.99e18); + fee = bound(fee, 0, 0.2e18); + amount1 = bound(amount1, 0.00001e18, 25e18); + amount2 = bound(amount2, 0.00001e18, 25e18); + + if (fee < 0.1e18) fee = 0; // half of the time use fee 0 + else fee -= 0.1e18; + + createMaglev(50e18, 50e18, fee, 1e18, 1e18, cx, cy); + + skimAll(preSkimDir); + int256 nav1 = getHolderNAV(); + + { + TestERC20 t1; + TestERC20 t2; + if (dir1) (t1, t2) = (assetTST, assetTST2); + else (t1, t2) = (assetTST2, assetTST); + + uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount1); + + t1.mint(address(this), amount1); + t1.transfer(address(maglev), amount1); + if (dir1) maglev.swap(0, q, address(this), ""); + else maglev.swap(q, 0, address(this), ""); + + skimAll(skimOrder1); + } + + assertGe(getHolderNAV(), nav1); + + { + TestERC20 t1; + TestERC20 t2; + if (dir2) (t1, t2) = (assetTST, assetTST2); + else (t1, t2) = (assetTST2, assetTST); + + uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount2); + + t1.mint(address(this), amount2); + t1.transfer(address(maglev), amount2); + if (dir2) maglev.swap(0, q, address(this), ""); + else maglev.swap(q, 0, address(this), ""); + + skimAll(skimOrder2); + } + + assertGe(getHolderNAV(), nav1); + } + + + + function _skimAll(bool dir) public 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 maglev.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 maglev.swap(amount0, amount1, address(0xDEAD), "") { + skimmed += val; + } catch { + if (val == 1) break; + } + } + + return skimmed; + } + + function skimAll(bool order) public { + if (order) { + _skimAll(true); + _skimAll(false); + } else { + _skimAll(false); + _skimAll(true); + } + } +} From a2a36da1d596597b249a218e6d8a9c07cbeefbf0 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 8 Feb 2025 00:26:24 -0500 Subject: [PATCH 094/312] fmt --- test/PreserveNav.t.sol | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/test/PreserveNav.t.sol b/test/PreserveNav.t.sol index bbb37b6..d95fc33 100644 --- a/test/PreserveNav.t.sol +++ b/test/PreserveNav.t.sol @@ -39,9 +39,18 @@ contract PreserveNav is MaglevTestBase { maglev.configure(); } - - - function test_preserve_nav(uint256 cx, uint256 cy, uint256 fee, bool preSkimDir, bool dir1, uint256 amount1, bool skimOrder1, bool dir2, uint256 amount2, bool skimOrder2) public { + function test_preserve_nav( + uint256 cx, + uint256 cy, + uint256 fee, + bool preSkimDir, + bool dir1, + uint256 amount1, + bool skimOrder1, + bool dir2, + uint256 amount2, + bool skimOrder2 + ) public { cx = bound(cx, 0.1e18, 0.99e18); cy = bound(cy, 0.1e18, 0.99e18); fee = bound(fee, 0, 0.2e18); @@ -49,6 +58,7 @@ contract PreserveNav is MaglevTestBase { amount2 = bound(amount2, 0.00001e18, 25e18); if (fee < 0.1e18) fee = 0; // half of the time use fee 0 + else fee -= 0.1e18; createMaglev(50e18, 50e18, fee, 1e18, 1e18, cx, cy); @@ -93,8 +103,6 @@ contract PreserveNav is MaglevTestBase { assertGe(getHolderNAV(), nav1); } - - function _skimAll(bool dir) public returns (uint256) { uint256 skimmed = 0; uint256 val = 1; From 77d549eb3737fd4714f53ae895d1da71b32c7e9f Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sat, 8 Feb 2025 14:48:39 -0500 Subject: [PATCH 095/312] large refactor --- README.md | 9 +-- src/MaglevBase.sol | 55 ++++++++++++- src/MaglevConstantProduct.sol | 6 +- src/MaglevConstantSum.sol | 6 +- src/MaglevEulerSwap.sol | 144 +++------------------------------- test/ConstantProduct.t.sol | 6 +- test/ConstantSum.t.sol | 4 +- test/EulerSwap.t.sol | 24 ++---- test/PreserveNav.t.sol | 24 ++++-- 9 files changed, 98 insertions(+), 180 deletions(-) diff --git a/README.md b/README.md index 8b901e4..38d795b 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ Maglev is a contract designed to be used as an [EVC operator](https://evc.wtf/do The following are the high-level steps required to use Maglev: -* Deposit funds into one or both of the vaults in proportion of the initial price +* Deposit funds into one or both of the vaults in proportion to the initial price * Deploy the desired Maglev contract, choosing parameters such as the vaults, debt limits, and the desired `fee` * Note that the Maglev contract must be created after the funds are deposited, because its constructor will read the current debts and balances to setup its reserves cache * Install the Maglev contract as an operator for your account @@ -114,11 +114,8 @@ With careful parameter selection, the EulerSwap curve supports optimal tradeoffs -## Todo +## Future directions -* The EulerSwap curve has some numerical instability that we believe is caused by rounding - * We think the biggest effect is that it may cause some swaps to fail even if the exact quoted amount is sent. Also, it may result in users slightly overpaying for swaps. - * The code currently has a quotePadding adjustment that seems to prevent this, but since we don't know a hard upper-bound it's hard to say if this solves it in all cases. In particular, this will only work well for 18-decimal tokens of reasonable prices * Currently we have only been supporting stable-stable pairs * What extra considerations would there be for floating pairs? * Automatically re-invest fees. There are a few options: @@ -145,6 +142,6 @@ With careful parameter selection, the EulerSwap curve supports optimal tradeoffs ## License -(c) 2024 Euler Labs Ltd. +(c) 2024-2025 Euler Labs Ltd. All rights reserved. diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index cdabe6f..572de76 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -27,6 +27,7 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { error InsufficientCash(); error DifferentEVC(); error AssetsOutOfOrderOrEqual(); + error CurveViolation(); modifier nonReentrant() { require(locked == 0, Locked()); @@ -125,7 +126,7 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { uint256 newReserve1 = reserve1 + amount1In - amount1Out; require(newReserve0 <= type(uint112).max && newReserve1 <= type(uint112).max, Overflow()); - verify(newReserve0, newReserve1); + require(verify(newReserve0, newReserve1), CurveViolation()); reserve0 = uint112(newReserve0); reserve1 = uint112(newReserve1); @@ -235,9 +236,55 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { return quote; } - // To be implemented by sub-class + /// @dev May be overridden by subclass if there is a more efficient method + /// of computing quotes than binary search. + function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) + internal + view + virtual + returns (uint256 output) + { + int256 dx; + int256 dy; + + if (exactIn) { + if (asset0IsInput) dx = int256(amount); + else dy = int256(amount); + } else { + if (asset0IsInput) dy = -int256(amount); + else dx = -int256(amount); + } + + unchecked { + int256 reserve0New = int256(uint256(reserve0)) + dx; + int256 reserve1New = int256(uint256(reserve1)) + dy; + + uint256 low; + uint256 mid; + uint256 high = type(uint112).max; - function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual; + for (uint256 i; i < 256; ++i) { + mid = (low + high) / 2; + bool valid = dx != 0 ? verify(uint256(reserve0New), mid) : verify(mid, uint256(reserve1New)); + if (valid) high = mid; + else low = mid + 1; + + if (low >= high) break; + } + + if (dx != 0) dy = int256(low) - reserve1New; + else dx = int256(low) - reserve0New; + } + + if (exactIn) { + if (asset0IsInput) output = uint256(-dy); + else output = uint256(-dx); + } else { + if (asset0IsInput) output = uint256(dx); + else output = uint256(dy); + } + } - function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view virtual returns (uint256); + /// @dev Must be implemented by sub-class + function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual returns (bool); } diff --git a/src/MaglevConstantProduct.sol b/src/MaglevConstantProduct.sol index 35169e8..1de41df 100644 --- a/src/MaglevConstantProduct.sol +++ b/src/MaglevConstantProduct.sol @@ -4,18 +4,16 @@ pragma solidity ^0.8.27; import {MaglevBase} from "./MaglevBase.sol"; contract MaglevConstantProduct is MaglevBase { - error KNotSatisfied(); - constructor(BaseParams memory baseParams) MaglevBase(baseParams) {} function k(uint256 r0, uint256 r1) public pure returns (uint256) { return r0 * r1; } - function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override { + function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override returns (bool) { uint256 kBefore = k(reserve0, reserve1); uint256 kAfter = k(newReserve0, newReserve1); - require(kAfter >= kBefore, KNotSatisfied()); + return kAfter >= kBefore; } function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol index b0cb273..d554818 100644 --- a/src/MaglevConstantSum.sol +++ b/src/MaglevConstantSum.sol @@ -7,8 +7,6 @@ contract MaglevConstantSum is MaglevBase { uint256 public immutable priceX; uint256 public immutable priceY; - error KNotSatisfied(); - struct ConstantSumParams { uint256 priceX; uint256 priceY; @@ -23,10 +21,10 @@ contract MaglevConstantSum is MaglevBase { return (r0 * priceX) + (r1 * priceY); } - function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override { + function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override returns (bool) { uint256 kBefore = k(reserve0, reserve1); uint256 kAfter = k(newReserve0, newReserve1); - require(kAfter >= kBefore, KNotSatisfied()); + return kAfter >= kBefore; } function computeQuote(uint256 amount, bool, bool) internal view virtual override returns (uint256) { diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index b3855a9..5f74c31 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; +import {Test, console} from "forge-std/Test.sol"; + import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {MaglevBase} from "./MaglevBase.sol"; import {IMaglevEulerSwap} from "./interfaces/IMaglevEulerSwap.sol"; @@ -13,10 +15,6 @@ contract MaglevEulerSwap is IMaglevEulerSwap, MaglevBase { uint112 public immutable initialReserve0; uint112 public immutable initialReserve1; - error KNotSatisfied(); - error ReservesZero(); - error InvalidInputCoordinate(); - struct EulerSwapParams { uint256 priceX; uint256 priceY; @@ -34,143 +32,21 @@ contract MaglevEulerSwap is IMaglevEulerSwap, MaglevBase { initialReserve1 = reserve1; } - function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override { - int256 delta = 0; - - if (newReserve0 >= initialReserve0) { - delta = int256(newReserve0) - - int256(fy(newReserve1, priceX, priceY, initialReserve0, initialReserve1, concentrationX, concentrationY)); - } else { - delta = int256(newReserve1) - - int256(fx(newReserve0, priceX, priceY, initialReserve0, initialReserve1, concentrationX, concentrationY)); - } - - // if delta is >= zero, then point is on or above the curve - require(delta >= 0, KNotSatisfied()); - } - - // Due to rounding, computeQuote() may underestimate the amount required to - // pass the verify() function. In order to prevent swaps from failing, quotes - // are inflated by this padding factor. - uint256 private constant quotePadding = 1.00000000001e18; - - function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) - internal - view - virtual - override - returns (uint256 output) - { - int256 dx; - int256 dy; - - if (exactIn) { - if (asset0IsInput) dx = int256(amount); - else dy = int256(amount); - } else { - if (asset0IsInput) dy = -int256(amount); - else dx = -int256(amount); - } - - { - int256 reserve0New = int256(uint256(reserve0)); - int256 reserve1New = int256(uint256(reserve1)); - - if (dx != 0) { - reserve0New += dx; - reserve1New = int256( - fx( - uint256(reserve0New), - priceX, - priceY, - initialReserve0, - initialReserve1, - concentrationX, - concentrationY - ) - ); - } - if (dy != 0) { - reserve1New += dy; - reserve0New = int256( - fy( - uint256(reserve1New), - priceX, - priceY, - initialReserve0, - initialReserve1, - concentrationX, - concentrationY - ) - ); - } - - dx = reserve0New - int256(uint256(reserve0)); - dy = reserve1New - int256(uint256(reserve1)); - } - - if (exactIn) { - if (asset0IsInput) output = uint256(-dy); - else output = uint256(-dx); - output = output * 1e18 / quotePadding; - } else { - if (asset0IsInput) output = uint256(dx); - else output = uint256(dy); - output = output * quotePadding / 1e18; - } - } - - ///// Curve math routines - - function fx(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) + function fx(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { - require(xt > 0, ReservesZero()); - if (xt <= x0) { - return fx1(xt, px, py, x0, y0, cx, cy); - } else { - return fx2(xt, px, py, x0, y0, cx, cy); - } + return y0 + px * 1e18 / py * (c * (2 * x0 - xt) / 1e18 + (1e18 - c) * x0 / 1e18 * x0 / xt - x0) / 1e18; } - function fy(uint256 yt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) - internal - pure - returns (uint256) - { - require(yt > 0, ReservesZero()); - if (yt <= y0) { - return fx1(yt, py, px, y0, x0, cy, cx); + function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override returns (bool) { + if (newReserve0 >= initialReserve0) { + if (newReserve1 >= initialReserve1) return true; + return newReserve0 >= fx(newReserve1, priceY, priceX, initialReserve1, initialReserve0, concentrationY); } else { - return fx2(yt, py, px, y0, x0, cy, cx); + if (newReserve1 < initialReserve1) return false; + return newReserve1 >= fx(newReserve0, priceX, priceY, initialReserve0, initialReserve1, concentrationX); } } - - function fx1(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256) - internal - pure - returns (uint256) - { - require(xt <= x0, InvalidInputCoordinate()); - return y0 + px * 1e18 / py * (cx * (2 * x0 - xt) / 1e18 + (1e18 - cx) * x0 / 1e18 * x0 / xt - x0) / 1e18; - } - - function fx2(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256, uint256 cy) - internal - pure - returns (uint256) - { - require(xt > x0, InvalidInputCoordinate()); - // intermediate values for solving quadratic equation - uint256 a = cy; - int256 b = (int256(px) * 1e18 / int256(py)) * (int256(xt) - int256(x0)) / 1e18 - + int256(y0) * (1e18 - 2 * int256(cy)) / 1e18; - int256 c = (int256(cy) - 1e18) * int256(y0) ** 2 / 1e18 / 1e18; - uint256 discriminant = uint256(int256(uint256(b ** 2)) - 4 * int256(a) * int256(c)); - uint256 numerator = uint256(-b + int256(uint256(Math.sqrt(discriminant)))); - uint256 denominator = 2 * a; - return numerator * 1e18 / denominator; - } } diff --git a/test/ConstantProduct.t.sol b/test/ConstantProduct.t.sol index b3d1e4d..6cf4b4b 100644 --- a/test/ConstantProduct.t.sol +++ b/test/ConstantProduct.t.sol @@ -8,7 +8,7 @@ import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; import {MaglevTestBase} from "./MaglevTestBase.t.sol"; -import {MaglevConstantProduct as Maglev} from "../src/MaglevConstantProduct.sol"; +import {MaglevConstantProduct as Maglev, MaglevBase} from "../src/MaglevConstantProduct.sol"; contract ConstantProductTest is MaglevTestBase { Maglev public maglev; @@ -39,7 +39,7 @@ contract ConstantProductTest is MaglevTestBase { assetTST.transfer(address(maglev), amount); - vm.expectRevert(Maglev.KNotSatisfied.selector); + vm.expectRevert(MaglevBase.CurveViolation.selector); maglev.swap(0, q + 1, address(this), ""); maglev.swap(0, q, address(this), ""); @@ -66,7 +66,7 @@ contract ConstantProductTest is MaglevTestBase { t1.transfer(address(maglev), amount); - vm.expectRevert(Maglev.KNotSatisfied.selector); + vm.expectRevert(MaglevBase.CurveViolation.selector); if (dir) maglev.swap(0, q + 1, address(this), ""); else maglev.swap(q + 1, 0, address(this), ""); diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index 7d1a805..2dfc1f0 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -8,7 +8,7 @@ import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; import {MaglevTestBase} from "./MaglevTestBase.t.sol"; -import {MaglevConstantSum as Maglev} from "../src/MaglevConstantSum.sol"; +import {MaglevConstantSum as Maglev, MaglevBase} from "../src/MaglevConstantSum.sol"; contract ConstantSumTest is MaglevTestBase { Maglev public maglev; @@ -199,7 +199,7 @@ contract ConstantSumTest is MaglevTestBase { tt.transfer(address(maglev), needed - 1); - vm.expectRevert(Maglev.KNotSatisfied.selector); + vm.expectRevert(MaglevBase.CurveViolation.selector); maglev.swap(a1, a2, recipient, ""); tt.transfer(address(maglev), 1); diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 893f2f0..353276f 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -125,12 +125,11 @@ contract EulerSwapTest is MaglevTestBase { assertEq(t2.balanceOf(address(this)), q); t2.transfer(address(maglev), q); - if (dir) maglev.swap(amount - 2, 0, address(this), ""); // - 2 due to rounding - - else maglev.swap(0, amount - 2, address(this), ""); + if (dir) maglev.swap(amount, 0, address(this), ""); + else maglev.swap(0, amount, address(this), ""); uint256 q2 = maglev.quoteExactInput(address(t1), address(t2), amount); - assertApproxEqAbs(q, q2, 0.00000001e18); + assertEq(q, q2); } function test_fuzzParams(uint256 amount, uint256 amount2, uint256 price, uint256 cx, uint256 cy, bool dir) public { @@ -173,17 +172,6 @@ contract EulerSwapTest is MaglevTestBase { assertGe(getHolderNAV(), origNAV); } - // To reproduce, change quotePadding to 1e18 - function test_roundingFailure() public { - uint256 amountIn = 1.4e18; - uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); - - assetTST.mint(address(this), amountIn); - assetTST.transfer(address(maglev), amountIn); - maglev.swap(0, amountOut, address(this), ""); - assertEq(assetTST2.balanceOf(address(this)), amountOut); - } - function test_fuzzAll(uint256 cx, uint256 cy, uint256 fee, uint256[8] calldata amounts, bool[8] calldata dirs) public { @@ -207,15 +195,19 @@ contract EulerSwapTest is MaglevTestBase { t1.mint(address(this), amount); uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount); + // Try to swap out 1 extra + t1.transfer(address(maglev), amount); { - uint256 qPlus = q * 1.00000000002e18 / 1e18; + uint256 qPlus = q + 1; vm.expectRevert(); if (dir) maglev.swap(0, qPlus, address(this), ""); else maglev.swap(qPlus, 0, address(this), ""); } + // Confirm actual quote works + uint256 prevBal = t2.balanceOf(address(this)); if (dir) maglev.swap(0, q, address(this), ""); else maglev.swap(q, 0, address(this), ""); diff --git a/test/PreserveNav.t.sol b/test/PreserveNav.t.sol index d95fc33..8f2810b 100644 --- a/test/PreserveNav.t.sol +++ b/test/PreserveNav.t.sol @@ -46,10 +46,8 @@ contract PreserveNav is MaglevTestBase { bool preSkimDir, bool dir1, uint256 amount1, - bool skimOrder1, bool dir2, - uint256 amount2, - bool skimOrder2 + uint256 amount2 ) public { cx = bound(cx, 0.1e18, 0.99e18); cy = bound(cy, 0.1e18, 0.99e18); @@ -76,10 +74,16 @@ contract PreserveNav is MaglevTestBase { t1.mint(address(this), amount1); t1.transfer(address(maglev), amount1); + + { + uint256 qPlus = q + 1; + vm.expectRevert(); + if (dir1) maglev.swap(0, qPlus, address(this), ""); + else maglev.swap(qPlus, 0, address(this), ""); + } + if (dir1) maglev.swap(0, q, address(this), ""); else maglev.swap(q, 0, address(this), ""); - - skimAll(skimOrder1); } assertGe(getHolderNAV(), nav1); @@ -94,10 +98,16 @@ contract PreserveNav is MaglevTestBase { t1.mint(address(this), amount2); t1.transfer(address(maglev), amount2); + + { + uint256 qPlus = q + 1; + vm.expectRevert(); + if (dir2) maglev.swap(0, qPlus, address(this), ""); + else maglev.swap(qPlus, 0, address(this), ""); + } + if (dir2) maglev.swap(0, q, address(this), ""); else maglev.swap(q, 0, address(this), ""); - - skimAll(skimOrder2); } assertGe(getHolderNAV(), nav1); From 5d1aae14cb16d88d3085f5a88bcecebe727845a7 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sun, 9 Feb 2025 15:43:54 -0500 Subject: [PATCH 096/312] cleanup --- src/MaglevBase.sol | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 572de76..5e9ec23 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -260,16 +260,12 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { int256 reserve1New = int256(uint256(reserve1)) + dy; uint256 low; - uint256 mid; uint256 high = type(uint112).max; - for (uint256 i; i < 256; ++i) { - mid = (low + high) / 2; - bool valid = dx != 0 ? verify(uint256(reserve0New), mid) : verify(mid, uint256(reserve1New)); - if (valid) high = mid; + while (low < high) { + uint256 mid = (low + high) / 2; + if (dy == 0 ? verify(uint256(reserve0New), mid) : verify(mid, uint256(reserve1New))) high = mid; else low = mid + 1; - - if (low >= high) break; } if (dx != 0) dy = int256(low) - reserve1New; From 2822bc50837945f31896698c7dc0ece45cba71a6 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 10 Feb 2025 15:59:50 -0500 Subject: [PATCH 097/312] some cleanup and natspec --- README.md | 2 +- src/MaglevBase.sol | 36 ++++++++++++++++++++++++---------- src/MaglevEulerSwap.sol | 6 +++--- src/interfaces/IMaglevBase.sol | 2 +- test/ConstantProduct.t.sol | 2 +- test/ConstantSum.t.sol | 2 +- test/EulerSwap.t.sol | 2 +- test/PreserveNav.t.sol | 2 +- test/UniswapV2Call.t.sol | 2 +- 9 files changed, 36 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 38d795b..27f2af1 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ The following are the high-level steps required to use Maglev: * Deploy the desired Maglev contract, choosing parameters such as the vaults, debt limits, and the desired `fee` * Note that the Maglev contract must be created after the funds are deposited, because its constructor will read the current debts and balances to setup its reserves cache * Install the Maglev contract as an operator for your account -* Invoke the `configure()` function on the Maglev contract +* Invoke the `activate()` function on the Maglev contract * This function can be invoked by anyone, and it is harmless to re-invoke it At this point, anyone can invoke `swap()` on the Maglev contract, and this will perform borrowing and transferring activity between the two vaults. diff --git a/src/MaglevBase.sol b/src/MaglevBase.sol index 5e9ec23..4f925f0 100644 --- a/src/MaglevBase.sol +++ b/src/MaglevBase.sol @@ -15,8 +15,8 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { address public immutable myAccount; uint256 public immutable feeMultiplier; - uint112 internal reserve0; - uint112 internal reserve1; + uint112 public reserve0; + uint112 public reserve1; uint32 internal locked; // uses single storage slot, accessible via getReserves() error Locked(); @@ -80,8 +80,10 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { // Owner functions - /// @dev Call *after* installing as operator - function configure() external { + /// @notice Approve the vaults to access the Maglev instance's tokens, + /// and enables vaults as collateral. Must call *after* installing + /// the Maglev instance as an operator. + function activate() external { IERC20(asset0).approve(vault0, type(uint256).max); IERC20(asset1).approve(vault1, type(uint256).max); @@ -91,6 +93,10 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { // Swapper interface + /// @notice Optimistically sends the requested amounts of tokens to the `to` + /// address, invokes `uniswapV2Call` callback on `to` (if `data` provided), and + /// then verifies that a sufficient amount of tokens were transferred to + /// satisfy the swapping curve invariant. function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external callThroughEVC @@ -137,16 +143,19 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { } } + /// @notice Convenience function for when both reserve values are needed. function getReserves() public view returns (uint112, uint112, uint32) { return (reserve0, reserve1, locked); } + /// @notice How much `tokenOut` can I get for `amountIn` of `tokenIn`? function quoteExactInput(address tokenIn, address tokenOut, uint256 amountIn) external view returns (uint256) { - return _computeQuote(tokenIn, tokenOut, amountIn, true); + return computeFullQuote(tokenIn, tokenOut, amountIn, true); } + /// @notice How much `tokenIn` do I need to get `amountOut` of `tokenOut`? function quoteExactOutput(address tokenIn, address tokenOut, uint256 amountOut) external view returns (uint256) { - return _computeQuote(tokenIn, tokenOut, amountOut, false); + return computeFullQuote(tokenIn, tokenOut, amountOut, false); } // Internal utilities @@ -205,7 +214,9 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { } } - function _computeQuote(address tokenIn, address tokenOut, uint256 amount, bool exactIn) + /// @dev This function handles quoting, including swap fees. Curve-specific + /// quote calculations are delegated to computeQuote(). + function computeFullQuote(address tokenIn, address tokenOut, uint256 amount, bool exactIn) internal view returns (uint256) @@ -236,8 +247,10 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { return quote; } - /// @dev May be overridden by subclass if there is a more efficient method - /// of computing quotes than binary search. + /// @dev This function generates quotes given the specific installed curve + /// instance. The base-class implementation is a binary search, however this + /// may be overridden by a subclass if there is a more efficient method + /// of computing quotes, or if a curve is non-convex. function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) internal view @@ -281,6 +294,9 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { } } - /// @dev Must be implemented by sub-class + /// @dev Function that defines the shape of the swapping curve. Returns true iff + /// the provided reserve amounts are acceptable to the pool. Geometrically, this + /// can be visualised as checking if a point is on or above/to the right of + /// the swapping curve. This function must be implemented by a sub-class. function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual returns (bool); } diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index 5f74c31..64dbd56 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -32,7 +32,7 @@ contract MaglevEulerSwap is IMaglevEulerSwap, MaglevBase { initialReserve1 = reserve1; } - function fx(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) + function f(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) @@ -43,10 +43,10 @@ contract MaglevEulerSwap is IMaglevEulerSwap, MaglevBase { function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override returns (bool) { if (newReserve0 >= initialReserve0) { if (newReserve1 >= initialReserve1) return true; - return newReserve0 >= fx(newReserve1, priceY, priceX, initialReserve1, initialReserve0, concentrationY); + return newReserve0 >= f(newReserve1, priceY, priceX, initialReserve1, initialReserve0, concentrationY); } else { if (newReserve1 < initialReserve1) return false; - return newReserve1 >= fx(newReserve0, priceX, priceY, initialReserve0, initialReserve1, concentrationX); + return newReserve1 >= f(newReserve0, priceX, priceY, initialReserve0, initialReserve1, concentrationX); } } } diff --git a/src/interfaces/IMaglevBase.sol b/src/interfaces/IMaglevBase.sol index 242ca74..e9dee80 100644 --- a/src/interfaces/IMaglevBase.sol +++ b/src/interfaces/IMaglevBase.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.0; interface IMaglevBase { - function configure() external; + function activate() external; function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; function quoteExactInput(address tokenIn, address tokenOut, uint256 amountIn) external view returns (uint256); function quoteExactOutput(address tokenIn, address tokenOut, uint256 amountOut) external view returns (uint256); diff --git a/test/ConstantProduct.t.sol b/test/ConstantProduct.t.sol index 6cf4b4b..2ca79cd 100644 --- a/test/ConstantProduct.t.sol +++ b/test/ConstantProduct.t.sol @@ -27,7 +27,7 @@ contract ConstantProductTest is MaglevTestBase { evc.setAccountOperator(holder, address(maglev), true); vm.prank(anyone); - maglev.configure(); + maglev.activate(); } function test_basicExactIn() public monotonicHolderNAV { diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol index 2dfc1f0..704f567 100644 --- a/test/ConstantSum.t.sol +++ b/test/ConstantSum.t.sol @@ -31,7 +31,7 @@ contract ConstantSumTest is MaglevTestBase { evc.setAccountOperator(holder, address(maglev), true); vm.prank(anyone); - maglev.configure(); + maglev.activate(); } function test_basicSwapReport() public monotonicHolderNAV { diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index 353276f..bfab83f 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -38,7 +38,7 @@ contract EulerSwapTest is MaglevTestBase { evc.setAccountOperator(holder, address(maglev), true); vm.prank(anyone); - maglev.configure(); + maglev.activate(); } function test_different_EVC() public { diff --git a/test/PreserveNav.t.sol b/test/PreserveNav.t.sol index 8f2810b..99cb30d 100644 --- a/test/PreserveNav.t.sol +++ b/test/PreserveNav.t.sol @@ -36,7 +36,7 @@ contract PreserveNav is MaglevTestBase { evc.setAccountOperator(holder, address(maglev), true); vm.prank(anyone); - maglev.configure(); + maglev.activate(); } function test_preserve_nav( diff --git a/test/UniswapV2Call.t.sol b/test/UniswapV2Call.t.sol index 66f9a8b..74eb2c7 100644 --- a/test/UniswapV2Call.t.sol +++ b/test/UniswapV2Call.t.sol @@ -37,7 +37,7 @@ contract UniswapV2CallTest is MaglevTestBase { evc.setAccountOperator(holder, address(maglev), true); vm.prank(anyone); - maglev.configure(); + maglev.activate(); } function test_callback() public { From 2ae434ab25ebce8f15e3015f3b4ea5cd23e46251 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 10 Feb 2025 16:00:19 -0500 Subject: [PATCH 098/312] fmt --- src/MaglevEulerSwap.sol | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol index 64dbd56..d0bf3a3 100644 --- a/src/MaglevEulerSwap.sol +++ b/src/MaglevEulerSwap.sol @@ -32,11 +32,7 @@ contract MaglevEulerSwap is IMaglevEulerSwap, MaglevBase { initialReserve1 = reserve1; } - function f(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) - internal - pure - returns (uint256) - { + function f(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { return y0 + px * 1e18 / py * (c * (2 * x0 - xt) / 1e18 + (1e18 - c) * x0 / 1e18 * x0 / xt - x0) / 1e18; } From f4922dda8242c6c950e5cf4f95bcbec9880e8778 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 11 Feb 2025 13:54:15 -0500 Subject: [PATCH 099/312] refactor into core/periphery --- README.md | 75 +++------- TODO | 66 +++++---- src/{MaglevBase.sol => Maglev.sol} | 210 ++++++++++------------------ src/MaglevConstantProduct.sol | 35 ----- src/MaglevConstantSum.sol | 34 ----- src/MaglevEulerSwap.sol | 48 ------- src/MaglevPeriphery.sol | 134 ++++++++++++++++++ src/interfaces/IMaglev.sol | 40 ++++++ src/interfaces/IMaglevBase.sol | 17 --- src/interfaces/IMaglevEulerSwap.sol | 13 -- src/interfaces/IMaglevPeriphery.sol | 16 +++ test/AltDecimals.t.sol | 118 ++++++++++++++++ test/ConstantProduct.t.sol | 140 ------------------- test/ConstantSum.t.sol | 210 ---------------------------- test/EulerSwap.t.sol | 43 +++--- test/MaglevTestBase.t.sol | 59 +++++++- test/PreserveNav.t.sol | 59 +------- test/UniswapV2Call.t.sol | 11 +- 18 files changed, 525 insertions(+), 803 deletions(-) rename src/{MaglevBase.sol => Maglev.sol} (51%) delete mode 100644 src/MaglevConstantProduct.sol delete mode 100644 src/MaglevConstantSum.sol delete mode 100644 src/MaglevEulerSwap.sol create mode 100644 src/MaglevPeriphery.sol create mode 100644 src/interfaces/IMaglev.sol delete mode 100644 src/interfaces/IMaglevBase.sol delete mode 100644 src/interfaces/IMaglevEulerSwap.sol create mode 100644 src/interfaces/IMaglevPeriphery.sol create mode 100644 test/AltDecimals.t.sol delete mode 100644 test/ConstantProduct.t.sol delete mode 100644 test/ConstantSum.t.sol diff --git a/README.md b/README.md index 27f2af1..9a87260 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Maglev is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) to **mag**nify capital efficiency using **lev**erage. By borrowing assets as needed, Maglev AMMs can extend the range of their reserves and earn fees on trades several times larger than their actual liquidity. -To swappers, Maglev presents a conventional Uniswap2-style interface but internally it supports borrow and repaying, custom pricing curves, and other advanced functionality. Although invokeable by anyone, the primary swapper user-base is intended to be aggregators, intents solvers, and MEV bots. +To swappers, Maglev presents a hopefully familiar Uniswap2-style interface but internally it supports borrow and repaying, custom pricing curves, and other advanced functionality. Although useable by anyone, it is primarily intended to be invoked by sophisticated actors such as swap aggregators, intents solvers, and MEV bots. Similar to Uniswap, there is a careful separation between the critical core functionality for servicing swaps and the surrounding periphery functions for quoting, etc. @@ -17,11 +17,7 @@ To swappers, Maglev presents a conventional Uniswap2-style interface but interna * [Debt Limits](#debt-limits) * [Desynchronised Reserves](#desynchronised-reserves) * [Fees](#fees) -* [Curves](#curves) - * [Constant Sum](#constant-sum) - * [Constant Product](#constant-product) - * [EulerSwap Curve](#eulerswap-curve) -* [Todo](#todo) +* [EulerSwap Curve](#eulerswap-curve) * [See Also](#see-also) * [Prior Art](#prior-art) * [License](#license) @@ -38,22 +34,19 @@ The down-side is that while the AMM holds this leveraged position, it is paying ## Operation -Since the level of acceptable borrowing risk is not be the same for every user, pooled deposits are not supported. Each Maglev instance manages funds for a single entity (who of course may be jointly owned). +Since the level of acceptable borrowing risk is not necessarily the same for every user, pooled deposits are not supported. Each Maglev instance manages funds for a single entity (which of course may be jointly owned). Maglev is a contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators). This means that the user, known as the *holder*, does not give up control over their funds to a smart contract, but instead retains it in their wallet. The holder can be any compatible address, including standard multisig wallets or even an EOA. ### Usage -The following are the high-level steps required to use Maglev: +The following are the high-level steps required to setup Maglev: * Deposit funds into one or both of the vaults in proportion to the initial price -* Deploy the desired Maglev contract, choosing parameters such as the vaults, debt limits, and the desired `fee` - * Note that the Maglev contract must be created after the funds are deposited, because its constructor will read the current debts and balances to setup its reserves cache +* Deploy the desired Maglev contract, choosing parameters such as the vaults, initial price ratio, debt limits, and the swapping fee + * Note that the Maglev contract must be created *after* the funds are deposited, because its constructor will read the current debts and balances to setup its reserves cache * Install the Maglev contract as an operator for your account -* Invoke the `activate()` function on the Maglev contract - * This function can be invoked by anyone, and it is harmless to re-invoke it - -At this point, anyone can invoke `swap()` on the Maglev contract, and this will perform borrowing and transferring activity between the two vaults. +* Optional: Invoke the `activate()` function on the Maglev contract. Otherwise, Maglev will be activated when the first swap is performed (increasing its gas cost somewhat) ### Reconfiguration @@ -61,7 +54,7 @@ All user-configurable parameters are stored in immutable variables, meaning they ### Debt Limits -The initial deposits in the two vaults represent the initial investment, and are swapped back and forth in response to swapping activity. In order to prevent loss to arbitrage, the initial investment should be made in proportion to the price of the assets. +The initial deposits in the two vaults represent the initial investment, and are swapped back and forth in response to swapping activity. In order to prevent immediate losses to arbitrage, the initial investment should be made in proportion to the price of the assets. In a conventional AMM such as Uniswap, the balances held by the contract are called *reserves*, and these represent a hard upper-bound on the amounts that can be swapped: In other words, no matter how much you are willing to pay, you can never receive more than the amount currently held in reserve. @@ -71,68 +64,32 @@ For example, if the initial investment has a NAV of $1000, and the debt limit is Each vault can have its own independent debt limit, which may be useful in case of vaults configured with asymmetric LTVs. A debt limit of 0 could be specified for one of the vaults if the holder only ever wants a borrow position in one of the assets. In the future we may add a debt minimum, allowing the holder to retain a position within a certain leverage range while continuing to profit off swapping activity. -Note that it depends on the [curve](#curves) if the maximum LTV can actually be achieved. A constant product curve will only approach these reserve levels asymptotically, since each unit will get more and more expensive. With a constant sum curve, the LTV can be achieved precisely. +Note that the the maximum LTV cannot actually be achieved because of the design of the curve. Instead, it will only approach these reserve levels asymptotically, since each unit gets more and more expensive. ### Desynchronised Reserves -The Maglev contract tracks what it believes the reserves (amount available plus borrowable) to be by caching in storage. These reserves are updated on each swap. However, since the balance is not actually held by the Maglev contract (it is simply an operator), the actual underlying debts and balances may get out of sync. This can happen gradually as interest and fees are accrued, or suddenly if the holder moves funds or the position is liquidated. +The Maglev contract tracks what it believes the reserves (balance available plus borrowable) to be by caching in storage. These reserves are updated on each swap. However, since the balance is not actually held by the Maglev contract (it is simply an operator), the actual underlying debts and balances may get out of sync. This can happen gradually as interest and fees are accrued, or suddenly if the holder moves funds or the position is liquidated. Normally this is not a problem, because swapping will still occur on the static curve (such actions do not change the offered prices). However, if there is a significant decrease in NAV then the desired LTVs may be exceeded (since the debt limit becomes higher relative to the NAV). If there is a significant increase in NAV then the AMM may become less capital efficient. To resynchronise, the Maglev instance should be uninstalled as an EVC operator, and a new one created and installed in its place. ### Fees -Maglev collects swap fees in the input token. - -When quoting exact input swaps the effective input amount is decreased by the fee (rounding down) before consulting the curve. When quoting exact output swaps, the required input amount is increased by the fee (rounding up). - -After depositing but prior to verifying the curve invariant, all input amounts are adjusted down (rounding down). - -Since the full amount including fees is actually deposited (or repaid), fees have the effect of increasing the NAV of the position. However, they are not currently "fed back" into the reserves to be used by future swaps. If fees build up significantly, the Maglev instance should be [replaced](#desynchronised-reserves). - - -## Curves +Maglev collects swap fees in the input token. In the core, after depositing but prior to verifying the curve invariant, all input amounts are adjusted down (rounding down). -### Constant Sum +In the periphery, when quoting exact input swaps the effective input amount is decreased by the fee (rounding down) before consulting the curve. When quoting exact output swaps, the required input amount is increased by the fee (rounding up). -This "curve" simply adds the values of the two reserves together and ensures that after a swap this sum has not decreased. It is mostly suitable for assets that are pegged to the same value, such as stable-stable pairs. +Since the full amount including fees is actually deposited (or repaid), fees have the effect of increasing the NAV of the position. However, they are not currently "fed back" into the reserves to be used by future swaps. If fees build up significantly, and compounding of these proceeds is desired, the Maglev instance should be [replaced](#desynchronised-reserves) by an instance with higher debt limits. -This curve supports a price fraction so that the two tokens can have different relative values, which can be useful if the peg is other than 1:1, or if the tokens have differing decimals. -In this curve, the entire virtual reserves can be consumed, and since each marginal unit of the swap has the same price, there is no direct incentive for arbitrageurs to deleverage the position. However, for the same reason this does allow fixed-size fees for swaps of any supported size (fixed price impact). +## EulerSwap Curve -### Constant Product +Although the Maglev interface can support various types of curves, the current implementation only uses the *EulerSwap curve*. This is a new curve developed by Euler Labs, and can be thought of as a hybrid between constant sum and constant product. The curve is defined piecewise: A piece to the left of an "initial reserves" point, and a piece to the right. -This is the traditional Uniswap2 curve that preserves the product of the two reserves. The larger a swap, the higher the price impact and the more profitable it is to arbitrage a disbalanced pool back to the market price. - -### EulerSwap Curve - -This is a new curve developed by Euler. It can be thought of as a hybrid between constant sum and constant product. The curve is defined piecewise: A piece to the left of an "initial reserves" point, and a piece to the right. - -Each piece has a `concentration` parameter that determines the trade-off between constant sum and constant product. The higher the concentration (closer to 1), the more it is similar to a constant sum, and the lower (closer to 0), a constant product. The curve is also parameterised by a `price` parameter which determines the slope at the initial reserves point. There are actually two price parameters which can be considered the numerator and denominator of the price fraction. +Each piece has a `concentration` parameter that determines the trade-off between constant sum and constant product. The higher the concentration (closer to 1), the more it resembles a constant sum, and the lower (closer to 0), a constant product. The curve is also parameterised by a `price` which determines the slope at the initial reserves point. There are actually two price parameters which can be considered the numerator and denominator of the price fraction. With careful parameter selection, the EulerSwap curve supports optimal tradeoffs between capital efficiency and arbitrage incentives. - -## Future directions - -* Currently we have only been supporting stable-stable pairs - * What extra considerations would there be for floating pairs? -* Automatically re-invest fees. There are a few options: - * Don't do anything: Re-deploing probably isn't a huge deal - * Increase the reserves by the fee amount - * Increase the reserves by the extra amount of possible leverage supported by the new fee - * Apply fees to a super-concentrated middle section of the curve (needs R&D) -* Could current reserves be calculated dynamically based on balances/debts/debt limits? - * I guess you would lose a chunk of interest to arbitrage - * Donation attacks? -* What can we do to make this easily integrated with aggregators/MEV bots/etc? - * For sure we need events. What should be logged? - * How to handle a discovery/tracking of the different Maglev instances? - * Factory? Registry? Maybe a fake factory that reads the actually installed operators from a set of addresses? -* Other misc stuff (see `TODO` file) - - ## See Also ### Prior Art diff --git a/TODO b/TODO index e4b184a..87d684f 100644 --- a/TODO +++ b/TODO @@ -1,28 +1,40 @@ -! events - * reserve change on each swap -! Better revert messages when a swap cannot be satisifed due to debt-limit/utilisation/etc +! Don't make quotes that would cause a swap to fail if supply/borrow caps exceeded +* Better revert messages when a swap fails due to maglev debt-limit/vault utilisation/etc * currently it's an arithmetic underflow -! Don't make quotes that would cause a swap to fail due to supply or borrow caps -* ConstantSum: incorporate price multipliers in quote methods -* natspec -* permit2 instead of regular approval: measure gas savings -? a really small swap could fail because deposit() results in 0 shares, which EVK fails on. call convertToShares() first? Seems like overkill -? pause guardian -? how should aggregators find instances - ? factory/registry contract - ? fake registry contract that looks at the actually installed operators for a list of accounts - ? transparent proxy so AMM address can stay constant - -docs - low-level detail of how system works for auditors - how to add a curve - information for aggregators - how to maintain quotes off-chain, including tracking cash from VaultStatus logs of underlying vaults - note how EVK stores balance and debt in same storage slot - -tests - prices/alternate decimals - especially quoting - when exchange rate in vaults != 1 - uniswap callback, flash swaps - hitting reserve/utilisation limits + + +TESTING + +* when exchange rate in vaults != 1 +* uniswap callback, flash swaps +* hitting reserve/utilisation limits +* AssetsOutOfOrderOrEqual + + +MISC + +? A really small swap could fail because deposit() results in 0 shares, which causes EVK to revert. Call convertToShares() first? Seems like overkill... +? permit2 instead of regular approval: measure gas savings +* Improve the efficiency of on-chain quoting + * Probably necessary for supporting non-zero slippage swaps + * Use unchecked math in verify() (needs careful boundary analysis) + * Closed-form quoting solutions + * "Range hints" for the binary search + + +IDEAS + +* Currently we have only been supporting stable-stable pairs + * What extra considerations would there be for floating pairs? +* Automatically re-invest fees? There are a few options: + * Don't do anything: Re-deploing probably isn't a huge deal + * Increase the reserves by the fee amount + * Increase the reserves by the extra amount of possible leverage supported by the new fee + * Apply fees to a super-concentrated middle section of the curve (needs R&D) +* Could current reserves be calculated dynamically based on balances/debts/debt limits? + * I guess you would lose a chunk of interest to arbitrage + * Donation attacks? +* What can we do to make this easily integrated with aggregators/MEV bots/etc? + * How to handle a discovery/tracking of the different Maglev instances? + ? Factory? Registry? Maybe a fake factory that reads the actually installed operators from a set of addresses? + ? Transparent proxy so a Maglev address can stay constant diff --git a/src/MaglevBase.sol b/src/Maglev.sol similarity index 51% rename from src/MaglevBase.sol rename to src/Maglev.sol index 4f925f0..0f567e7 100644 --- a/src/MaglevBase.sol +++ b/src/Maglev.sol @@ -5,38 +5,60 @@ import {EVCUtil} from "evc/utils/EVCUtil.sol"; import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault, IERC20, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; import {IUniswapV2Callee} from "./interfaces/IUniswapV2Callee.sol"; -import {IMaglevBase} from "./interfaces/IMaglevBase.sol"; +import {IMaglev} from "./interfaces/IMaglev.sol"; + +contract Maglev is IMaglev, EVCUtil { + bytes32 public constant curve = keccak256("EulerSwap v1"); -abstract contract MaglevBase is IMaglevBase, EVCUtil { address public immutable vault0; address public immutable vault1; address public immutable asset0; address public immutable asset1; address public immutable myAccount; + uint112 public immutable debtLimit0; + uint112 public immutable debtLimit1; + uint112 public immutable initialReserve0; + uint112 public immutable initialReserve1; uint256 public immutable feeMultiplier; + uint256 public immutable priceX; + uint256 public immutable priceY; + uint256 public immutable concentrationX; + uint256 public immutable concentrationY; + uint112 public reserve0; uint112 public reserve1; - uint32 internal locked; // uses single storage slot, accessible via getReserves() + uint32 public status; // 0 = unactivated, 1 = unlocked, 2 = locked error Locked(); error Overflow(); - error UnsupportedPair(); error BadFee(); - error InsufficientReserves(); - error InsufficientCash(); error DifferentEVC(); error AssetsOutOfOrderOrEqual(); error CurveViolation(); + event MaglevCreated(address indexed maglev, address indexed asset0, address indexed asset1); + + event Swap( + address indexed sender, + uint256 amount0In, + uint256 amount1In, + uint256 amount0Out, + uint256 amount1Out, + uint112 reserve0, + uint112 reserve1, + address indexed to + ); + modifier nonReentrant() { - require(locked == 0, Locked()); - locked = 1; + if (status == 0) activate(); + require(status == 1, Locked()); + status = 2; _; - locked = 0; + status = 1; } - struct BaseParams { + struct Params { address evc; address vault0; address vault1; @@ -46,18 +68,16 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { uint256 fee; } - event Swap( - address indexed sender, - uint256 amount0In, - uint256 amount1In, - uint256 amount0Out, - uint256 amount1Out, - uint112 reserve0, - uint112 reserve1, - address indexed to - ); + struct CurveParams { + uint256 priceX; + uint256 priceY; + uint256 concentrationX; + uint256 concentrationY; + } + + constructor(Params memory params, CurveParams memory curveParams) EVCUtil(params.evc) { + // Maglev params - constructor(BaseParams memory params) EVCUtil(params.evc) { require(params.fee < 1e18, BadFee()); address vault0Evc = IEVault(params.vault0).EVC(); @@ -68,22 +88,32 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { address asset1Addr = IEVault(params.vault1).asset(); require(asset0Addr < asset1Addr, AssetsOutOfOrderOrEqual()); - myAccount = params.myAccount; vault0 = params.vault0; vault1 = params.vault1; asset0 = asset0Addr; asset1 = asset1Addr; - reserve0 = offsetReserve(params.debtLimit0, params.vault0); - reserve1 = offsetReserve(params.debtLimit1, params.vault1); + myAccount = params.myAccount; + debtLimit0 = params.debtLimit0; + debtLimit1 = params.debtLimit1; + initialReserve0 = reserve0 = offsetReserve(params.debtLimit0, params.vault0); + initialReserve1 = reserve1 = offsetReserve(params.debtLimit1, params.vault1); feeMultiplier = 1e18 - params.fee; + + // Curve params + + priceX = curveParams.priceX; + priceY = curveParams.priceY; + concentrationX = curveParams.concentrationX; + concentrationY = curveParams.concentrationY; + + emit MaglevCreated(address(this), asset0Addr, asset1Addr); } - // Owner functions + /// @inheritdoc IMaglev + function activate() public { + require(status != 2, Locked()); + status = 1; - /// @notice Approve the vaults to access the Maglev instance's tokens, - /// and enables vaults as collateral. Must call *after* installing - /// the Maglev instance as an operator. - function activate() external { IERC20(asset0).approve(vault0, type(uint256).max); IERC20(asset1).approve(vault1, type(uint256).max); @@ -91,12 +121,23 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { IEVC(evc).enableCollateral(myAccount, vault1); } - // Swapper interface + /// @dev EulerSwap curve definition + function f(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { + return y0 + px * 1e18 / py * (c * (2 * x0 - xt) / 1e18 + (1e18 - c) * x0 / 1e18 * x0 / xt - x0) / 1e18; + } + + /// @inheritdoc IMaglev + function verify(uint256 newReserve0, uint256 newReserve1) public view returns (bool) { + if (newReserve0 >= initialReserve0) { + if (newReserve1 >= initialReserve1) return true; + return newReserve0 >= f(newReserve1, priceY, priceX, initialReserve1, initialReserve0, concentrationY); + } else { + if (newReserve1 < initialReserve1) return false; + return newReserve1 >= f(newReserve0, priceX, priceY, initialReserve0, initialReserve1, concentrationX); + } + } - /// @notice Optimistically sends the requested amounts of tokens to the `to` - /// address, invokes `uniswapV2Call` callback on `to` (if `data` provided), and - /// then verifies that a sufficient amount of tokens were transferred to - /// satisfy the swapping curve invariant. + /// @inheritdoc IMaglev function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external callThroughEVC @@ -143,19 +184,8 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { } } - /// @notice Convenience function for when both reserve values are needed. - function getReserves() public view returns (uint112, uint112, uint32) { - return (reserve0, reserve1, locked); - } - - /// @notice How much `tokenOut` can I get for `amountIn` of `tokenIn`? - function quoteExactInput(address tokenIn, address tokenOut, uint256 amountIn) external view returns (uint256) { - return computeFullQuote(tokenIn, tokenOut, amountIn, true); - } - - /// @notice How much `tokenIn` do I need to get `amountOut` of `tokenOut`? - function quoteExactOutput(address tokenIn, address tokenOut, uint256 amountOut) external view returns (uint256) { - return computeFullQuote(tokenIn, tokenOut, amountOut, false); + function getReserves() external view returns (uint112, uint112, uint32) { + return (reserve0, reserve1, status); } // Internal utilities @@ -213,90 +243,4 @@ abstract contract MaglevBase is IMaglevBase, EVCUtil { } } } - - /// @dev This function handles quoting, including swap fees. Curve-specific - /// quote calculations are delegated to computeQuote(). - function computeFullQuote(address tokenIn, address tokenOut, uint256 amount, bool exactIn) - internal - view - returns (uint256) - { - // exactIn: decrease received amountIn, rounding down - if (exactIn) amount = amount * feeMultiplier / 1e18; - - bool asset0IsInput; - if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true; - else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; - else revert UnsupportedPair(); - - uint256 quote = computeQuote(amount, exactIn, asset0IsInput); - - if (exactIn) { - // if `exactIn`, `quote` is the amount of assets to buy from the AMM - require(quote <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); - require(quote <= IEVault(asset0IsInput ? vault1 : vault0).cash(), InsufficientCash()); - } else { - // if `!exactIn`, `amount` is the amount of assets to buy from the AMM - require(amount <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); - require(amount <= IEVault(asset0IsInput ? vault1 : vault0).cash(), InsufficientCash()); - } - - // exactOut: increase required quote(amountIn), rounding up - if (!exactIn) quote = (quote * 1e18 + (feeMultiplier - 1)) / feeMultiplier; - - return quote; - } - - /// @dev This function generates quotes given the specific installed curve - /// instance. The base-class implementation is a binary search, however this - /// may be overridden by a subclass if there is a more efficient method - /// of computing quotes, or if a curve is non-convex. - function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) - internal - view - virtual - returns (uint256 output) - { - int256 dx; - int256 dy; - - if (exactIn) { - if (asset0IsInput) dx = int256(amount); - else dy = int256(amount); - } else { - if (asset0IsInput) dy = -int256(amount); - else dx = -int256(amount); - } - - unchecked { - int256 reserve0New = int256(uint256(reserve0)) + dx; - int256 reserve1New = int256(uint256(reserve1)) + dy; - - uint256 low; - uint256 high = type(uint112).max; - - while (low < high) { - uint256 mid = (low + high) / 2; - if (dy == 0 ? verify(uint256(reserve0New), mid) : verify(mid, uint256(reserve1New))) high = mid; - else low = mid + 1; - } - - if (dx != 0) dy = int256(low) - reserve1New; - else dx = int256(low) - reserve0New; - } - - if (exactIn) { - if (asset0IsInput) output = uint256(-dy); - else output = uint256(-dx); - } else { - if (asset0IsInput) output = uint256(dx); - else output = uint256(dy); - } - } - - /// @dev Function that defines the shape of the swapping curve. Returns true iff - /// the provided reserve amounts are acceptable to the pool. Geometrically, this - /// can be visualised as checking if a point is on or above/to the right of - /// the swapping curve. This function must be implemented by a sub-class. - function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual returns (bool); } diff --git a/src/MaglevConstantProduct.sol b/src/MaglevConstantProduct.sol deleted file mode 100644 index 1de41df..0000000 --- a/src/MaglevConstantProduct.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.27; - -import {MaglevBase} from "./MaglevBase.sol"; - -contract MaglevConstantProduct is MaglevBase { - constructor(BaseParams memory baseParams) MaglevBase(baseParams) {} - - function k(uint256 r0, uint256 r1) public pure returns (uint256) { - return r0 * r1; - } - - function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override returns (bool) { - uint256 kBefore = k(reserve0, reserve1); - uint256 kAfter = k(newReserve0, newReserve1); - return kAfter >= kBefore; - } - - function computeQuote(uint256 amount, bool exactIn, bool asset0IsInput) - internal - view - virtual - override - returns (uint256) - { - uint256 reserveIn = asset0IsInput ? reserve0 : reserve1; - uint256 reserveOut = asset0IsInput ? reserve1 : reserve0; - - if (exactIn) { - return (reserveOut * amount) / (reserveIn + amount); - } else { - return (reserveIn * amount) / (reserveOut - amount); - } - } -} diff --git a/src/MaglevConstantSum.sol b/src/MaglevConstantSum.sol deleted file mode 100644 index d554818..0000000 --- a/src/MaglevConstantSum.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.27; - -import {MaglevBase} from "./MaglevBase.sol"; - -contract MaglevConstantSum is MaglevBase { - uint256 public immutable priceX; - uint256 public immutable priceY; - - struct ConstantSumParams { - uint256 priceX; - uint256 priceY; - } - - constructor(BaseParams memory baseParams, ConstantSumParams memory params) MaglevBase(baseParams) { - priceX = params.priceX; - priceY = params.priceY; - } - - function k(uint256 r0, uint256 r1) public view returns (uint256) { - return (r0 * priceX) + (r1 * priceY); - } - - function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override returns (bool) { - uint256 kBefore = k(reserve0, reserve1); - uint256 kAfter = k(newReserve0, newReserve1); - return kAfter >= kBefore; - } - - function computeQuote(uint256 amount, bool, bool) internal view virtual override returns (uint256) { - // FIXME: use priceX and priceY - return amount; - } -} diff --git a/src/MaglevEulerSwap.sol b/src/MaglevEulerSwap.sol deleted file mode 100644 index d0bf3a3..0000000 --- a/src/MaglevEulerSwap.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.27; - -import {Test, console} from "forge-std/Test.sol"; - -import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; -import {MaglevBase} from "./MaglevBase.sol"; -import {IMaglevEulerSwap} from "./interfaces/IMaglevEulerSwap.sol"; - -contract MaglevEulerSwap is IMaglevEulerSwap, MaglevBase { - uint256 public immutable priceX; - uint256 public immutable priceY; - uint256 public immutable concentrationX; - uint256 public immutable concentrationY; - uint112 public immutable initialReserve0; - uint112 public immutable initialReserve1; - - struct EulerSwapParams { - uint256 priceX; - uint256 priceY; - uint256 concentrationX; - uint256 concentrationY; - } - - constructor(BaseParams memory baseParams, EulerSwapParams memory params) MaglevBase(baseParams) { - priceX = params.priceX; - priceY = params.priceY; - concentrationX = params.concentrationX; - concentrationY = params.concentrationY; - - initialReserve0 = reserve0; - initialReserve1 = reserve1; - } - - function f(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { - return y0 + px * 1e18 / py * (c * (2 * x0 - xt) / 1e18 + (1e18 - c) * x0 / 1e18 * x0 / xt - x0) / 1e18; - } - - function verify(uint256 newReserve0, uint256 newReserve1) internal view virtual override returns (bool) { - if (newReserve0 >= initialReserve0) { - if (newReserve1 >= initialReserve1) return true; - return newReserve0 >= f(newReserve1, priceY, priceX, initialReserve1, initialReserve0, concentrationY); - } else { - if (newReserve1 < initialReserve1) return false; - return newReserve1 >= f(newReserve0, priceX, priceY, initialReserve0, initialReserve1, concentrationX); - } - } -} diff --git a/src/MaglevPeriphery.sol b/src/MaglevPeriphery.sol new file mode 100644 index 0000000..930aa93 --- /dev/null +++ b/src/MaglevPeriphery.sol @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.27; + +import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; +import {IMaglev} from "./interfaces/IMaglev.sol"; +import {IMaglevPeriphery} from "./interfaces/IMaglevPeriphery.sol"; + +contract MaglevPeriphery is IMaglevPeriphery { + address private immutable evc; + + constructor(address evc_) { + evc = evc_; + } + + error UnsupportedPair(); + error OperatorNotInstalled(); + error InsufficientReserves(); + error InsufficientCash(); + + /// @inheritdoc IMaglevPeriphery + function quoteExactInput(address maglev, address tokenIn, address tokenOut, uint256 amountIn) + external + view + returns (uint256) + { + return computeQuote(IMaglev(maglev), tokenIn, tokenOut, amountIn, true); + } + + /// @inheritdoc IMaglevPeriphery + function quoteExactOutput(address maglev, address tokenIn, address tokenOut, uint256 amountOut) + external + view + returns (uint256) + { + return computeQuote(IMaglev(maglev), tokenIn, tokenOut, amountOut, false); + } + + /// @dev High-level quoting function. It handles fees and performs + /// state validation, for example that there is sufficient cash available. + function computeQuote(IMaglev maglev, address tokenIn, address tokenOut, uint256 amount, bool exactIn) + internal + view + returns (uint256) + { + require(IEVC(evc).isAccountOperatorAuthorized(maglev.myAccount(), address(maglev)), OperatorNotInstalled()); + + uint256 feeMultiplier = maglev.feeMultiplier(); + address vault0 = maglev.vault0(); + address vault1 = maglev.vault1(); + (uint112 reserve0, uint112 reserve1,) = maglev.getReserves(); + + // exactIn: decrease received amountIn, rounding down + if (exactIn) amount = amount * feeMultiplier / 1e18; + + bool asset0IsInput; + { + address asset0 = maglev.asset0(); + address asset1 = maglev.asset1(); + + if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true; + else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; + else revert UnsupportedPair(); + } + + uint256 quote = binarySearch(maglev, reserve0, reserve1, amount, exactIn, asset0IsInput); + + if (exactIn) { + // if `exactIn`, `quote` is the amount of assets to buy from the AMM + require(quote <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); + require(quote <= IEVault(asset0IsInput ? vault1 : vault0).cash(), InsufficientCash()); + } else { + // if `!exactIn`, `amount` is the amount of assets to buy from the AMM + require(amount <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); + require(amount <= IEVault(asset0IsInput ? vault1 : vault0).cash(), InsufficientCash()); + } + + // exactOut: increase required quote(amountIn), rounding up + if (!exactIn) quote = (quote * 1e18 + (feeMultiplier - 1)) / feeMultiplier; + + return quote; + } + + /// @dev General-purpose routine for binary searching swapping curves. + /// Although some curves may have more efficient closed-form solutions, + /// this works with any monotonic curve. + function binarySearch( + IMaglev maglev, + uint112 reserve0, + uint112 reserve1, + uint256 amount, + bool exactIn, + bool asset0IsInput + ) internal view returns (uint256 output) { + int256 dx; + int256 dy; + + if (exactIn) { + if (asset0IsInput) dx = int256(amount); + else dy = int256(amount); + } else { + if (asset0IsInput) dy = -int256(amount); + else dx = -int256(amount); + } + + unchecked { + int256 reserve0New = int256(uint256(reserve0)) + dx; + int256 reserve1New = int256(uint256(reserve1)) + dy; + + uint256 low; + uint256 high = type(uint112).max; + + while (low < high) { + uint256 mid = (low + high) / 2; + if (dy == 0 ? maglev.verify(uint256(reserve0New), mid) : maglev.verify(mid, uint256(reserve1New))) { + high = mid; + } else { + low = mid + 1; + } + } + + if (dx != 0) dy = int256(low) - reserve1New; + else dx = int256(low) - reserve0New; + } + + if (exactIn) { + if (asset0IsInput) output = uint256(-dy); + else output = uint256(-dx); + } else { + if (asset0IsInput) output = uint256(dx); + else output = uint256(dy); + } + } +} diff --git a/src/interfaces/IMaglev.sol b/src/interfaces/IMaglev.sol new file mode 100644 index 0000000..0d54352 --- /dev/null +++ b/src/interfaces/IMaglev.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +interface IMaglev { + /// @notice Optimistically sends the requested amounts of tokens to the `to` + /// address, invokes `uniswapV2Call` callback on `to` (if `data` was provided), + /// and then verifies that a sufficient amount of tokens were transferred to + /// satisfy the swapping curve invariant. + function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; + + /// @notice Approves the vaults to access the Maglev instance's tokens, and enables + /// vaults as collateral. Can be invoked by anybody, and is harmless if invoked again. + /// Calling this function is optional: Maglev can be activated on the first swap. + function activate() external; + + /// @notice Function that defines the shape of the swapping curve. Returns true iff + /// the specified reserve amounts would be acceptable (ie it is above and to-the-right + /// of the swapping curve). + function verify(uint256 newReserve0, uint256 newReserve1) external view returns (bool); + + // Maglev Accessors + + function curve() external view returns (bytes32); + function vault0() external view returns (address); + function vault1() external view returns (address); + function asset0() external view returns (address); + function asset1() external view returns (address); + function myAccount() external view returns (address); + function initialReserve0() external view returns (uint112); + function initialReserve1() external view returns (uint112); + function feeMultiplier() external view returns (uint256); + function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 status); + + // Curve Accessors + + function priceX() external view returns (uint256); + function priceY() external view returns (uint256); + function concentrationX() external view returns (uint256); + function concentrationY() external view returns (uint256); +} diff --git a/src/interfaces/IMaglevBase.sol b/src/interfaces/IMaglevBase.sol deleted file mode 100644 index e9dee80..0000000 --- a/src/interfaces/IMaglevBase.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.0; - -interface IMaglevBase { - function activate() external; - function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; - function quoteExactInput(address tokenIn, address tokenOut, uint256 amountIn) external view returns (uint256); - function quoteExactOutput(address tokenIn, address tokenOut, uint256 amountOut) external view returns (uint256); - - function vault0() external view returns (address); - function vault1() external view returns (address); - function asset0() external view returns (address); - function asset1() external view returns (address); - function myAccount() external view returns (address); - function feeMultiplier() external view returns (uint256); - function getReserves() external view returns (uint112, uint112, uint32); -} diff --git a/src/interfaces/IMaglevEulerSwap.sol b/src/interfaces/IMaglevEulerSwap.sol deleted file mode 100644 index 3902449..0000000 --- a/src/interfaces/IMaglevEulerSwap.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.0; - -import {IMaglevBase} from "./IMaglevBase.sol"; - -interface IMaglevEulerSwap is IMaglevBase { - function priceX() external view returns (uint256); - function priceY() external view returns (uint256); - function concentrationX() external view returns (uint256); - function concentrationY() external view returns (uint256); - function initialReserve0() external view returns (uint112); - function initialReserve1() external view returns (uint112); -} diff --git a/src/interfaces/IMaglevPeriphery.sol b/src/interfaces/IMaglevPeriphery.sol new file mode 100644 index 0000000..3b6f5c8 --- /dev/null +++ b/src/interfaces/IMaglevPeriphery.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +interface IMaglevPeriphery { + /// @notice How much `tokenOut` can I get for `amountIn` of `tokenIn`? + function quoteExactInput(address maglev, address tokenIn, address tokenOut, uint256 amountIn) + external + view + returns (uint256); + + /// @notice How much `tokenIn` do I need to get `amountOut` of `tokenOut`? + function quoteExactOutput(address maglev, address tokenIn, address tokenOut, uint256 amountOut) + external + view + returns (uint256); +} diff --git a/test/AltDecimals.t.sol b/test/AltDecimals.t.sol new file mode 100644 index 0000000..069d1de --- /dev/null +++ b/test/AltDecimals.t.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.24; + +import {Test, console} from "forge-std/Test.sol"; + +import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; +import {MaglevTestBase} from "./MaglevTestBase.t.sol"; + +import {Maglev} from "../src/Maglev.sol"; + +contract AltDecimals is MaglevTestBase { + Maglev public maglev; + + function setUp() public virtual override { + super.setUp(); + } + + function createMaglev( + uint112 debtLimitA, + uint112 debtLimitB, + uint256 fee, + uint256 px, + uint256 py, + uint256 cx, + uint256 cy + ) internal { + vm.prank(creator); + maglev = new Maglev( + getMaglevParams(debtLimitA, debtLimitB, fee), + Maglev.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) + ); + + vm.prank(holder); + evc.setAccountOperator(holder, address(maglev), true); + } + + function test_alt_decimals_6_18_in() public { + createMaglev(50e6, 50e18, 0, 1e18, 1e6, 0.9e18, 0.9e18); + skimAll(maglev, true); + + uint256 amount = 1e6; + uint256 q = periphery.quoteExactInput(address(maglev), address(assetTST), address(assetTST2), amount); + assertApproxEqAbs(q, 1e18, 0.01e18); + + assetTST.mint(address(this), amount); + assetTST.transfer(address(maglev), amount); + + { + uint256 qPlus = q + 1; + vm.expectRevert(); + maglev.swap(0, qPlus, address(this), ""); + } + + maglev.swap(0, q, address(this), ""); + } + + function test_alt_decimals_6_18_out() public { + createMaglev(50e6, 50e18, 0, 1e18, 1e6, 0.9e18, 0.9e18); + skimAll(maglev, true); + + uint256 amount = 1e18; + uint256 q = periphery.quoteExactOutput(address(maglev), address(assetTST), address(assetTST2), amount); + assertApproxEqAbs(q, 1e6, 0.01e6); + + assetTST.mint(address(this), q); + assetTST.transfer(address(maglev), q); + + { + uint256 amountPlus = amount + 0.0000001e18; + vm.expectRevert(); + maglev.swap(0, amountPlus, address(this), ""); + } + + maglev.swap(0, amount, address(this), ""); + } + + function test_alt_decimals_18_6_in() public { + createMaglev(50e18, 50e6, 0, 1e6, 1e18, 0.9e18, 0.9e18); + skimAll(maglev, true); + + uint256 amount = 1e18; + uint256 q = periphery.quoteExactInput(address(maglev), address(assetTST), address(assetTST2), amount); + assertApproxEqAbs(q, 1e6, 0.01e6); + + assetTST.mint(address(this), amount); + assetTST.transfer(address(maglev), amount); + + { + uint256 qPlus = q + 1; + vm.expectRevert(); + maglev.swap(0, qPlus, address(this), ""); + } + + maglev.swap(0, q, address(this), ""); + } + + function test_alt_decimals_18_6_out() public { + createMaglev(50e18, 50e6, 0, 1e6, 1e18, 0.9e18, 0.9e18); + skimAll(maglev, false); + + uint256 amount = 1e6; + uint256 q = periphery.quoteExactOutput(address(maglev), address(assetTST), address(assetTST2), amount); + assertApproxEqAbs(q, 1e18, 0.01e18); + + assetTST.mint(address(this), q); + assetTST.transfer(address(maglev), q); + + { + uint256 amountPlus = amount + 1; + vm.expectRevert(); + maglev.swap(0, amountPlus, address(this), ""); + } + + maglev.swap(0, amount, address(this), ""); + } +} diff --git a/test/ConstantProduct.t.sol b/test/ConstantProduct.t.sol deleted file mode 100644 index 2ca79cd..0000000 --- a/test/ConstantProduct.t.sol +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.8.24; - -import {Test, console} from "forge-std/Test.sol"; - -import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; -import {IEVault} from "evk/EVault/IEVault.sol"; -import {MaglevTestBase} from "./MaglevTestBase.t.sol"; - -import {MaglevConstantProduct as Maglev, MaglevBase} from "../src/MaglevConstantProduct.sol"; - -contract ConstantProductTest is MaglevTestBase { - Maglev public maglev; - - function setUp() public virtual override { - super.setUp(); - - createMaglev(50e18, 50e18, 0); - } - - function createMaglev(uint112 debtLimitA, uint112 debtLimitB, uint256 fee) internal { - vm.prank(creator); - maglev = new Maglev(getMaglevBaseParams(debtLimitA, debtLimitB, fee)); - - vm.prank(holder); - evc.setAccountOperator(holder, address(maglev), true); - - vm.prank(anyone); - maglev.activate(); - } - - function test_basicExactIn() public monotonicHolderNAV { - uint256 amount = 1e18; - - assetTST.mint(address(this), amount); - - uint256 q = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount); - - assetTST.transfer(address(maglev), amount); - - vm.expectRevert(MaglevBase.CurveViolation.selector); - maglev.swap(0, q + 1, address(this), ""); - - maglev.swap(0, q, address(this), ""); - assertEq(assetTST2.balanceOf(address(this)), q); - } - - function test_fee_exactIn(uint256 amount, bool dir) public monotonicHolderNAV { - amount = bound(amount, 0.1e18, 25e18); - - TestERC20 t1; - TestERC20 t2; - if (dir) (t1, t2) = (assetTST, assetTST2); - else (t1, t2) = (assetTST2, assetTST); - - t1.mint(address(this), amount); - - uint256 qOrig = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount * 0.998e18 / 1e18); - - createMaglev(50e18, 50e18, 0.002e18); - - uint256 q = maglev.quoteExactInput(address(assetTST), address(assetTST2), amount); - - assertEq(qOrig, q); - - t1.transfer(address(maglev), amount); - - vm.expectRevert(MaglevBase.CurveViolation.selector); - if (dir) maglev.swap(0, q + 1, address(this), ""); - else maglev.swap(q + 1, 0, address(this), ""); - - if (dir) maglev.swap(0, q, address(this), ""); - else maglev.swap(q, 0, address(this), ""); - assertEq(t2.balanceOf(address(this)), q); - } - - function test_pathIndependent(uint256 amount, bool dir) public monotonicHolderNAV { - amount = bound(amount, 0.1e18, 25e18); - - TestERC20 t1; - TestERC20 t2; - if (dir) (t1, t2) = (assetTST, assetTST2); - else (t1, t2) = (assetTST2, assetTST); - - t1.mint(address(this), amount); - - uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount); - - t1.transfer(address(maglev), amount); - if (dir) maglev.swap(0, q, address(this), ""); - else maglev.swap(q, 0, address(this), ""); - assertEq(t2.balanceOf(address(this)), q); - - t2.transfer(address(maglev), q); - if (dir) maglev.swap(amount - 2, 0, address(this), ""); // - 2 due to rounding - - else maglev.swap(0, amount - 2, address(this), ""); - - uint256 q2 = maglev.quoteExactInput(address(t1), address(t2), amount); - assertApproxEqAbs(q, q2, 2); - } - - function test_fuzzAll(uint256 fee, uint256[8] calldata amounts, bool[8] calldata dirs) public { - fee = bound(fee, 0, 0.1e18); - - createMaglev(50e18, 50e18, fee); - - int256 origNAV = getHolderNAV(); - - for (uint256 i = 0; i < 8; i++) { - uint256 amount = bound(amounts[i], 0.1e18, 5e18); - bool dir = dirs[i]; - - TestERC20 t1; - TestERC20 t2; - if (dir) (t1, t2) = (assetTST, assetTST2); - else (t1, t2) = (assetTST2, assetTST); - - t1.mint(address(this), amount); - uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount); - - t1.transfer(address(maglev), amount); - - { - uint256 qPlus = q + 1; - vm.expectRevert(); - if (dir) maglev.swap(0, qPlus, address(this), ""); - else maglev.swap(qPlus, 0, address(this), ""); - } - - uint256 prevBal = t2.balanceOf(address(this)); - if (dir) maglev.swap(0, q, address(this), ""); - else maglev.swap(q, 0, address(this), ""); - assertEq(t2.balanceOf(address(this)), q + prevBal); - - assertGe(getHolderNAV(), origNAV); - } - } -} diff --git a/test/ConstantSum.t.sol b/test/ConstantSum.t.sol deleted file mode 100644 index 704f567..0000000 --- a/test/ConstantSum.t.sol +++ /dev/null @@ -1,210 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.8.24; - -import {Test, console} from "forge-std/Test.sol"; - -import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; -import {IEVault} from "evk/EVault/IEVault.sol"; -import {MaglevTestBase} from "./MaglevTestBase.t.sol"; - -import {MaglevConstantSum as Maglev, MaglevBase} from "../src/MaglevConstantSum.sol"; - -contract ConstantSumTest is MaglevTestBase { - Maglev public maglev; - - function setUp() public virtual override { - super.setUp(); - - createMaglev(50e18, 50e18, 0, 1, 1); - } - - function createMaglev(uint112 debtLimitA, uint112 debtLimitB, uint256 fee, uint256 priceX, uint256 priceY) - internal - { - vm.prank(creator); - maglev = new Maglev( - getMaglevBaseParams(debtLimitA, debtLimitB, fee), Maglev.ConstantSumParams({priceX: priceX, priceY: priceY}) - ); - - vm.prank(holder); - evc.setAccountOperator(holder, address(maglev), true); - - vm.prank(anyone); - maglev.activate(); - } - - function test_basicSwapReport() public monotonicHolderNAV { - uint256 amount = 25e18; - assetTST.mint(address(this), amount); - - logState(address(maglev)); - - assetTST.transfer(address(maglev), amount); - maglev.swap(0, amount, address(this), ""); - assertEq(assetTST2.balanceOf(address(this)), amount); - - logState(address(maglev)); - - uint256 amount2 = 50e18; - assetTST2.mint(address(this), amount2); - assetTST2.transfer(address(maglev), amount2); - maglev.swap(amount2, 0, address(this), ""); - - assetTST2.transfer(address(maglev), 1e18); - maglev.swap(1e18, 0, address(this), ""); - - logState(address(maglev)); - } - - function test_reserveLimit() public monotonicHolderNAV { - (uint112 reserve0, uint112 reserve1,) = maglev.getReserves(); - assertEq(reserve0, 60e18); - assertEq(reserve1, 60e18); - - assetTST.mint(address(this), 1000e18); - - uint256 snapshot = vm.snapshotState(); - - { - uint256 amount = 60.000001e18; - assetTST.transfer(address(maglev), amount); - vm.expectRevert(); // FIXME: currently an arithmetic underflow. should make this a proper error - maglev.swap(0, amount, address(this), ""); - } - - vm.revertToState(snapshot); - - { - uint256 amount = 60e18; - assetTST.transfer(address(maglev), amount); - maglev.swap(0, amount, address(this), ""); - } - - (reserve0, reserve1,) = maglev.getReserves(); - - assertEq(eTST.balanceOf(holder), 70e18); - assertEq(eTST2.debtOf(holder), 50e18); - assertEq(reserve0, 120e18); - assertEq(reserve1, 0e18); - - // Same debt limit means reserves not affected - - createMaglev(50e18, 50e18, 0, 1, 1); - - (reserve0, reserve1,) = maglev.getReserves(); - - assertEq(reserve0, 120e18); - assertEq(reserve1, 0e18); - - // Increase debt limit on one side - - createMaglev(50e18, 55e18, 0, 1, 1); - - (reserve0, reserve1,) = maglev.getReserves(); - - assertEq(reserve0, 120e18); - assertEq(reserve1, 5e18); - - // And the other - - createMaglev(55e18, 55e18, 0, 1, 1); - - (reserve0, reserve1,) = maglev.getReserves(); - - assertEq(reserve0, 125e18); - assertEq(reserve1, 5e18); - - // Shrink debt limit - - createMaglev(40e18, 45e18, 0, 1, 1); - - (reserve0, reserve1,) = maglev.getReserves(); - - assertEq(reserve0, 110e18); - assertEq(reserve1, 0e18); // can't go below 0 - } - - function test_basicSwapFuzz(uint256 amount1, uint256 amount2) public monotonicHolderNAV { - amount1 = bound(amount1, 1e18, 25e18); - amount2 = bound(amount2, 1e18, 50e18); - - assetTST.mint(address(this), amount1); - assetTST.transfer(address(maglev), amount1); - maglev.swap(0, amount1, address(this), ""); - assertEq(assetTST.balanceOf(address(this)), 0); - assertEq(assetTST2.balanceOf(address(this)), amount1); - - assetTST2.mint(address(this), amount2); - assetTST2.transfer(address(maglev), amount2); - maglev.swap(amount2, 0, address(this), ""); - assertEq(assetTST.balanceOf(address(this)), amount2); - assertEq(assetTST2.balanceOf(address(this)), amount1); - } - - function test_quoteExactInput() public monotonicHolderNAV { - createMaglev(50e18, 50e18, 0.003e18, 1, 1); - - assetTST.mint(address(this), 100e18); - - uint256 q = maglev.quoteExactInput(address(assetTST), address(assetTST2), 1e18); - assertEq(q, 0.997e18); - assetTST.transfer(address(maglev), 1e18); - - maglev.swap(0, q, recipient, ""); - assertEq(assetTST2.balanceOf(recipient), q); - } - - function test_quoteExactOutput() public monotonicHolderNAV { - createMaglev(50e18, 50e18, 0.003e18, 1, 1); - - assetTST.mint(address(this), 100e18); - - uint256 q = maglev.quoteExactOutput(address(assetTST), address(assetTST2), 1e18); - assertEq(q, 1.003009027081243732e18); - assetTST.transfer(address(maglev), q); - - maglev.swap(0, 1e18, recipient, ""); - assertEq(assetTST2.balanceOf(recipient), 1e18); - } - - function test_fees(uint256 fee, uint256 amount1, bool token0) public monotonicHolderNAV { - fee = bound(fee, 0, 0.02e18); - amount1 = bound(amount1, 1e18, 25e18); - - createMaglev(50e18, 50e18, fee, 1, 1); - - assetTST.mint(address(this), 100e18); - assetTST2.mint(address(this), 100e18); - - uint256 feeMultiplier = 1e18 - fee; - uint256 needed = (amount1 * 1e18 + (feeMultiplier - 1)) / feeMultiplier; - - TestERC20 tt; - TestERC20 tt2; - uint256 a1; - uint256 a2; - - if (token0) { - tt = assetTST; - tt2 = assetTST2; - a1 = 0; - a2 = amount1; - } else { - tt = assetTST2; - tt2 = assetTST; - a1 = amount1; - a2 = 0; - } - - tt.transfer(address(maglev), needed - 1); - - vm.expectRevert(MaglevBase.CurveViolation.selector); - maglev.swap(a1, a2, recipient, ""); - - tt.transfer(address(maglev), 1); - maglev.swap(a1, a2, recipient, ""); - - assertEq(tt2.balanceOf(recipient), amount1); - } -} diff --git a/test/EulerSwap.t.sol b/test/EulerSwap.t.sol index bfab83f..7316600 100644 --- a/test/EulerSwap.t.sol +++ b/test/EulerSwap.t.sol @@ -8,7 +8,7 @@ import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; import {MaglevTestBase} from "./MaglevTestBase.t.sol"; -import {MaglevEulerSwap as Maglev, MaglevBase} from "../src/MaglevEulerSwap.sol"; +import {Maglev} from "../src/Maglev.sol"; contract EulerSwapTest is MaglevTestBase { Maglev public maglev; @@ -30,22 +30,19 @@ contract EulerSwapTest is MaglevTestBase { ) internal { vm.prank(creator); maglev = new Maglev( - getMaglevBaseParams(debtLimitA, debtLimitB, fee), - Maglev.EulerSwapParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) + getMaglevParams(debtLimitA, debtLimitB, fee), + Maglev.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) ); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); - - vm.prank(anyone); - maglev.activate(); } function test_different_EVC() public { - vm.expectRevert(MaglevBase.DifferentEVC.selector); + vm.expectRevert(Maglev.DifferentEVC.selector); new Maglev( - MaglevBase.BaseParams({ + Maglev.Params({ evc: address(makeAddr("RANDOM_EVC")), vault0: address(eTST), vault1: address(eTST2), @@ -54,13 +51,13 @@ contract EulerSwapTest is MaglevTestBase { debtLimit1: 50e18, fee: 0 }), - Maglev.EulerSwapParams({priceX: 1e18, priceY: 1e18, concentrationX: 4e18, concentrationY: 0.85e18}) + Maglev.CurveParams({priceX: 1e18, priceY: 1e18, concentrationX: 4e18, concentrationY: 0.85e18}) ); } function test_basicSwap_exactIn() public monotonicHolderNAV { uint256 amountIn = 1e18; - uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); + uint256 amountOut = periphery.quoteExactInput(address(maglev), address(assetTST), address(assetTST2), amountIn); assertApproxEqAbs(amountOut, 0.9974e18, 0.0001e18); assetTST.mint(address(this), amountIn); @@ -73,7 +70,7 @@ contract EulerSwapTest is MaglevTestBase { function test_basicSwap_exactOut() public monotonicHolderNAV { uint256 amountOut = 1e18; - uint256 amountIn = maglev.quoteExactOutput(address(assetTST), address(assetTST2), amountOut); + uint256 amountIn = periphery.quoteExactOutput(address(maglev), address(assetTST), address(assetTST2), amountOut); assertApproxEqAbs(amountIn, 1.0025e18, 0.0001e18); assetTST.mint(address(this), amountIn); @@ -96,7 +93,7 @@ contract EulerSwapTest is MaglevTestBase { createMaglev(50e18, 50e18, 0, px, py, 0.4e18, 0.85e18); uint256 amountIn = 1e18; - uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); + uint256 amountOut = periphery.quoteExactInput(address(maglev), address(assetTST), address(assetTST2), amountIn); assetTST.mint(address(this), amountIn); @@ -117,7 +114,7 @@ contract EulerSwapTest is MaglevTestBase { t1.mint(address(this), amount); - uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount); + uint256 q = periphery.quoteExactInput(address(maglev), address(t1), address(t2), amount); t1.transfer(address(maglev), amount); if (dir) maglev.swap(0, q, address(this), ""); @@ -128,7 +125,7 @@ contract EulerSwapTest is MaglevTestBase { if (dir) maglev.swap(amount, 0, address(this), ""); else maglev.swap(0, amount, address(this), ""); - uint256 q2 = maglev.quoteExactInput(address(t1), address(t2), amount); + uint256 q2 = periphery.quoteExactInput(address(maglev), address(t1), address(t2), amount); assertEq(q, q2); } @@ -139,12 +136,14 @@ contract EulerSwapTest is MaglevTestBase { cx = bound(cx, 0.01e18, 0.99e18); cy = bound(cy, 0.01e18, 0.99e18); - uint256 px = price; - uint256 py = 1e18; - oracle.setPrice(address(eTST), unitOfAccount, price); - oracle.setPrice(address(assetTST), unitOfAccount, price); + { + uint256 px = price; + uint256 py = 1e18; + oracle.setPrice(address(eTST), unitOfAccount, price); + oracle.setPrice(address(assetTST), unitOfAccount, price); - createMaglev(50e18, 50e18, 0, px, py, cx, cy); + createMaglev(50e18, 50e18, 0, px, py, cx, cy); + } int256 origNAV = getHolderNAV(); @@ -154,7 +153,7 @@ contract EulerSwapTest is MaglevTestBase { else (t1, t2) = (assetTST2, assetTST); t1.mint(address(this), amount); - uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount); + uint256 q = periphery.quoteExactInput(address(maglev), address(t1), address(t2), amount); t1.transfer(address(maglev), amount); if (dir) maglev.swap(0, q, address(this), ""); @@ -162,7 +161,7 @@ contract EulerSwapTest is MaglevTestBase { assertEq(t2.balanceOf(address(this)), q); t2.mint(address(this), amount2); - uint256 q2 = maglev.quoteExactInput(address(t2), address(t1), amount2); + uint256 q2 = periphery.quoteExactInput(address(maglev), address(t2), address(t1), amount2); t2.transfer(address(maglev), amount2); if (dir) maglev.swap(q2, 0, address(this), ""); @@ -193,7 +192,7 @@ contract EulerSwapTest is MaglevTestBase { else (t1, t2) = (assetTST2, assetTST); t1.mint(address(this), amount); - uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount); + uint256 q = periphery.quoteExactInput(address(maglev), address(t1), address(t2), amount); // Try to swap out 1 extra diff --git a/test/MaglevTestBase.t.sol b/test/MaglevTestBase.t.sol index a6112c3..a77d5c4 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/MaglevTestBase.t.sol @@ -7,7 +7,8 @@ import {Test, console} from "forge-std/Test.sol"; import {EVaultTestBase, TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; -import {MaglevBase} from "../src/MaglevBase.sol"; +import {Maglev} from "../src/Maglev.sol"; +import {MaglevPeriphery} from "../src/MaglevPeriphery.sol"; contract MaglevTestBase is EVaultTestBase { address public depositor = makeAddr("depositor"); @@ -16,9 +17,13 @@ contract MaglevTestBase is EVaultTestBase { address public recipient = makeAddr("recipient"); address public anyone = makeAddr("anyone"); + MaglevPeriphery public periphery; + function setUp() public virtual override { super.setUp(); + periphery = new MaglevPeriphery(address(evc)); + // Vault config eTST.setLTV(address(eTST2), 0.9e4, 0.9e4, 0); @@ -43,12 +48,12 @@ contract MaglevTestBase is EVaultTestBase { _mintAndDeposit(holder, eTST2, 10e18); } - function getMaglevBaseParams(uint112 debtLimitA, uint112 debtLimitB, uint256 fee) + function getMaglevParams(uint112 debtLimitA, uint112 debtLimitB, uint256 fee) internal view - returns (MaglevBase.BaseParams memory) + returns (Maglev.Params memory) { - return MaglevBase.BaseParams({ + return Maglev.Params({ evc: address(evc), vault0: address(eTST), vault1: address(eTST2), @@ -91,7 +96,7 @@ contract MaglevTestBase is EVaultTestBase { } function logState(address ml) internal view { - (uint112 reserve0, uint112 reserve1,) = MaglevBase(ml).getReserves(); + (uint112 reserve0, uint112 reserve1,) = Maglev(ml).getReserves(); console.log("--------------------"); console.log("Account States:"); @@ -103,4 +108,48 @@ contract MaglevTestBase is EVaultTestBase { console.log(" reserve0: ", reserve0); console.log(" reserve1: ", reserve1); } + + function _skimAll(Maglev 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 skimAll(Maglev ml, bool order) public { + if (order) { + _skimAll(ml, true); + _skimAll(ml, false); + } else { + _skimAll(ml, false); + _skimAll(ml, true); + } + } } diff --git a/test/PreserveNav.t.sol b/test/PreserveNav.t.sol index 99cb30d..69da5e4 100644 --- a/test/PreserveNav.t.sol +++ b/test/PreserveNav.t.sol @@ -8,7 +8,7 @@ import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; import {MaglevTestBase} from "./MaglevTestBase.t.sol"; -import {MaglevEulerSwap as Maglev, MaglevBase} from "../src/MaglevEulerSwap.sol"; +import {Maglev} from "../src/Maglev.sol"; contract PreserveNav is MaglevTestBase { Maglev public maglev; @@ -28,15 +28,12 @@ contract PreserveNav is MaglevTestBase { ) internal { vm.prank(creator); maglev = new Maglev( - getMaglevBaseParams(debtLimitA, debtLimitB, fee), - Maglev.EulerSwapParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) + getMaglevParams(debtLimitA, debtLimitB, fee), + Maglev.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) ); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); - - vm.prank(anyone); - maglev.activate(); } function test_preserve_nav( @@ -61,7 +58,7 @@ contract PreserveNav is MaglevTestBase { createMaglev(50e18, 50e18, fee, 1e18, 1e18, cx, cy); - skimAll(preSkimDir); + skimAll(maglev, preSkimDir); int256 nav1 = getHolderNAV(); { @@ -70,7 +67,7 @@ contract PreserveNav is MaglevTestBase { if (dir1) (t1, t2) = (assetTST, assetTST2); else (t1, t2) = (assetTST2, assetTST); - uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount1); + uint256 q = periphery.quoteExactInput(address(maglev), address(t1), address(t2), amount1); t1.mint(address(this), amount1); t1.transfer(address(maglev), amount1); @@ -94,7 +91,7 @@ contract PreserveNav is MaglevTestBase { if (dir2) (t1, t2) = (assetTST, assetTST2); else (t1, t2) = (assetTST2, assetTST); - uint256 q = maglev.quoteExactInput(address(t1), address(t2), amount2); + uint256 q = periphery.quoteExactInput(address(maglev), address(t1), address(t2), amount2); t1.mint(address(this), amount2); t1.transfer(address(maglev), amount2); @@ -112,48 +109,4 @@ contract PreserveNav is MaglevTestBase { assertGe(getHolderNAV(), nav1); } - - function _skimAll(bool dir) public 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 maglev.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 maglev.swap(amount0, amount1, address(0xDEAD), "") { - skimmed += val; - } catch { - if (val == 1) break; - } - } - - return skimmed; - } - - function skimAll(bool order) public { - if (order) { - _skimAll(true); - _skimAll(false); - } else { - _skimAll(false); - _skimAll(true); - } - } } diff --git a/test/UniswapV2Call.t.sol b/test/UniswapV2Call.t.sol index 74eb2c7..e103eda 100644 --- a/test/UniswapV2Call.t.sol +++ b/test/UniswapV2Call.t.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.24; import {IUniswapV2Callee} from "../src/interfaces/IUniswapV2Callee.sol"; // import {Test, console} from "forge-std/Test.sol"; import {MaglevTestBase} from "./MaglevTestBase.t.sol"; -import {MaglevEulerSwap as Maglev} from "../src/MaglevEulerSwap.sol"; +import {Maglev} from "../src/Maglev.sol"; contract UniswapV2CallTest is MaglevTestBase { Maglev public maglev; @@ -29,20 +29,17 @@ contract UniswapV2CallTest is MaglevTestBase { ) internal { vm.prank(creator); maglev = new Maglev( - getMaglevBaseParams(debtLimitA, debtLimitB, fee), - Maglev.EulerSwapParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) + getMaglevParams(debtLimitA, debtLimitB, fee), + Maglev.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) ); vm.prank(holder); evc.setAccountOperator(holder, address(maglev), true); - - vm.prank(anyone); - maglev.activate(); } function test_callback() public { uint256 amountIn = 1e18; - uint256 amountOut = maglev.quoteExactInput(address(assetTST), address(assetTST2), amountIn); + uint256 amountOut = periphery.quoteExactInput(address(maglev), address(assetTST), address(assetTST2), amountIn); assertApproxEqAbs(amountOut, 0.9974e18, 0.0001e18); assetTST.mint(address(this), amountIn); From b013fd0a24079b212e3efd62a721de5eb9f33a0c Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Thu, 13 Feb 2025 12:44:14 +0000 Subject: [PATCH 100/312] feat: add white paper --- docs/white-paper/Maglev_White_Paper.pdf | Bin 0 -> 337375 bytes docs/white-paper/curve.png | Bin 0 -> 262544 bytes docs/white-paper/main.tex | 499 ++++++++++++++++++++++++ docs/white-paper/references.bib | 91 +++++ 4 files changed, 590 insertions(+) create mode 100644 docs/white-paper/Maglev_White_Paper.pdf create mode 100644 docs/white-paper/curve.png create mode 100644 docs/white-paper/main.tex create mode 100644 docs/white-paper/references.bib diff --git a/docs/white-paper/Maglev_White_Paper.pdf b/docs/white-paper/Maglev_White_Paper.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f86000f0417acee4f7b01dda82489bfd471c7db4 GIT binary patch literal 337375 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 literal 0 HcmV?d00001 diff --git a/docs/white-paper/curve.png b/docs/white-paper/curve.png new file mode 100644 index 0000000000000000000000000000000000000000..59176ba7d8fc3119a72051a0a4b33dde2a6f3352 GIT binary patch literal 262544 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

9RT#VV)`zi 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

i*SUSkw=3S+ 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 Qa%Ev{lVt*Nm&zpt74{{dJpcdz delta 50043 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

IUKB@GP|%3E*y_h=ldYHcJU*evMWG=zMVAiynR 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
Kl_Dby53jDL~F_T!+FzYD~Zju<%%lDFPW=^I7 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 From 61c2dff787027af2699aaafc0fb17a6b63a6d598 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 13 Feb 2025 16:09:21 +0100 Subject: [PATCH 105/312] chore: rename EulerSwapTest to MaglevTest --- test/{EulerSwap.t.sol => MaglevTest.t.sol} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename test/{EulerSwap.t.sol => MaglevTest.t.sol} (99%) diff --git a/test/EulerSwap.t.sol b/test/MaglevTest.t.sol similarity index 99% rename from test/EulerSwap.t.sol rename to test/MaglevTest.t.sol index 7316600..fdb00b1 100644 --- a/test/EulerSwap.t.sol +++ b/test/MaglevTest.t.sol @@ -10,7 +10,7 @@ import {MaglevTestBase} from "./MaglevTestBase.t.sol"; import {Maglev} from "../src/Maglev.sol"; -contract EulerSwapTest is MaglevTestBase { +contract MaglevTest is MaglevTestBase { Maglev public maglev; function setUp() public virtual override { From 978a93105f963b7ecb823d99b22f8cac5891b695 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Thu, 13 Feb 2025 17:58:47 +0000 Subject: [PATCH 106/312] rename to euler-swap in white paper and readme --- README.md | 54 ++++++++--------- docs/maglev.png | Bin 270813 -> 0 bytes ...te_Paper.pdf => EulerSwap_White_Paper.pdf} | Bin 339532 -> 338838 bytes docs/white-paper/main.tex | 56 +++++++++--------- 4 files changed, 52 insertions(+), 58 deletions(-) delete mode 100644 docs/maglev.png rename docs/white-paper/{Maglev_White_Paper.pdf => EulerSwap_White_Paper.pdf} (82%) diff --git a/README.md b/README.md index e2aabee..25a0ffb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ -# Euler Maglev +# Euler Swap -![maglev logo](docs/maglev.png) - -Maglev is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) as leveraged lending products in order to extend the range of its reserves and thereby improve the capital efficiency of liquidity provisioning. +EulerSwap is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) as leveraged lending products in order to extend the range of its reserves and thereby improve the capital efficiency of liquidity provisioning. To swappers, it presents a conventional Uniswap2-style interface but internally it supports custom pricing curves and other advanced functionality. @@ -10,21 +8,21 @@ To swappers, it presents a conventional Uniswap2-style interface but internally -* [Concept](#concept) -* [Operation](#operation) - * [Usage](#usage) - * [Virtual Reserves](#virtual-reserves) - * [Desynchronised Virtual Reserves](#desynchronised-virtual-reserves) -* [Curves](#curves) - * [Constant Sum](#constant-sum) - * [Constant Product](#constant-product) -* [License](#license) +- [Concept](#concept) +- [Operation](#operation) + - [Usage](#usage) + - [Virtual Reserves](#virtual-reserves) + - [Desynchronised Virtual Reserves](#desynchronised-virtual-reserves) +- [Curves](#curves) + - [Constant Sum](#constant-sum) + - [Constant Product](#constant-product) +- [License](#license) ## Concept -Given a fixed size investment, Maglev aims to increase the size of trades that can be serviced, relative to a conventional AMM such as Uniswap. It does this by borrowing the "out token" and collateralising this loan with the received "in token". Later on, when somebody wishes to swap in the reverse direction, the loan can be repaid in exchange for receiving the collateral, unwinding the borrow position. +Given a fixed size investment, EulerSwap aims to increase the size of trades that can be serviced, relative to a conventional AMM such as Uniswap. It does this by borrowing the "out token" and collateralising this loan with the received "in token". Later on, when somebody wishes to swap in the reverse direction, the loan can be repaid in exchange for receiving the collateral, unwinding the borrow position. Because the total size of the position can be many times larger than your initial investment (depending on how much LTV/leverage is allowed on the underlying lending pools), the swapping fees earned can be magnified. @@ -32,27 +30,27 @@ The down-side is that while the AMM holds this leveraged position, it is paying ## Operation -Since the level of acceptable borrowing risk may not be the same for every user, pooled deposits are not yet possible, and each Maglev instance manages funds for a single user (who of course may operate on behalf of pooled funds). +Since the level of acceptable borrowing risk may not be the same for every user, pooled deposits are not yet possible, and each EulerSwap instance manages funds for a single user (who of course may operate on behalf of pooled funds). -Maglev is a contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators). This means that the user, known as the *holder*, does not give up control over their funds to a smart contract, but instead retains it in their wallet. The holder can be any compatible address, including standard multisig wallets or even an EOA. +EulerSwap is a contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators). This means that the user, known as the _holder_, does not give up control over their funds to a smart contract, but instead retains it in their wallet. The holder can be any compatible address, including standard multisig wallets or even an EOA. ### Usage -The following are the high-level steps required to use Maglev: +The following are the high-level steps required to use EulerSwap: -* Deposit funds into one or both of the vaults -* Deploy the desired Maglev contract, choosing parameters such as the vaults and the desired `fee` -* Calculate the desired [virtual reserves](#virtual-reserves) and set these values by invoking `setVirtualReserves()` -* Install the Maglev contract as an operator for your account -* Invoke the `configure()` function on the Maglev contract +- Deposit funds into one or both of the vaults +- Deploy the desired EulerSwap contract, choosing parameters such as the vaults and the desired `fee` +- Calculate the desired [virtual reserves](#virtual-reserves) and set these values by invoking `setVirtualReserves()` +- Install the EulerSwap contract as an operator for your account +- Invoke the `configure()` function on the EulerSwap contract -At this point, anyone can invoke `swap()` on the Maglev contract, and this will perform borrowing and transferring activity between the two vaults. +At this point, anyone can invoke `swap()` on the EulerSwap contract, and this will perform borrowing and transferring activity between the two vaults. ### Virtual Reserves -The initial deposits in the vaults represent the initial investment, and are swapped back and forth in response to swapping activity. In a conventional AMM such as Uniswap, these balance are called *reserves*. However, if swapping was constrained to these assets alone, then this would imply a hard limit on the size of swaps that can be serviced. To increase the effective funds, Maglev AMMs are configured with *virtual reserves*. These are typically larger than the size of the conventional reserves, which signifies that not only can all the assets be swapped from one vault to another, but even more assets can be borrowed on the Maglev's account. +The initial deposits in the vaults represent the initial investment, and are swapped back and forth in response to swapping activity. In a conventional AMM such as Uniswap, these balance are called _reserves_. However, if swapping was constrained to these assets alone, then this would imply a hard limit on the size of swaps that can be serviced. To increase the effective funds, EulerSwap AMMs are configured with _virtual reserves_. These are typically larger than the size of the conventional reserves, which signifies that not only can all the assets be swapped from one vault to another, but even more assets can be borrowed on the EulerSwap's account. -Virtual reserves control the maximum debt that the Maglev contract will attempt to acquire on each of its two vaults. Each vault can be configured independently. +Virtual reserves control the maximum debt that the EulerSwap contract will attempt to acquire on each of its two vaults. Each vault can be configured independently. For example, if the initial investment has a NAV of $1000, and virtual reserves are configured at $5000 for each vault, then the maximum LTV loan that the AMM will support will be `5000/6000 = 0.8333`. In order to leave a safety buffer, it is recommended to select a maximum LTV that is below the borrowing LTV of the vault. @@ -60,12 +58,10 @@ Note that it depends on the [curve](#curves) if the maximum LTV can actually be ### Desynchronised Virtual Reserves -The Maglev contract tracks what it believes the reserves to be by caching their values in storage. These reserves are updated on each swap. However, since the balance is not actually held by the Maglev contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest is accrued, or suddenly if the holder moves funds or the position is liquidated. +The EulerSwap contract tracks what it believes the reserves to be by caching their values in storage. These reserves are updated on each swap. However, since the balance is not actually held by the EulerSwap contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest is accrued, or suddenly if the holder moves funds or the position is liquidated. When this occurs, the `syncVirtualReserves()` should be invoked. This determines the actual balances (and debts) of the holder, and adjusts them by the configured virtual reserve levels. - - ## Curves ### Constant Sum @@ -80,8 +76,6 @@ In this curve, the entire virtual reserves can be consumed, and since each margi This is the traditional Uniswap2 curve that preserves the product of the two reserves. The larger a swap, the higher the price impact and the more profitable it is to arbitrage a disbalanced pool back to its wider market price. - - ## License (c) 2024 Euler Labs Ltd. diff --git a/docs/maglev.png b/docs/maglev.png deleted file mode 100644 index 700067ad375a8934276fd2b575fcb6e5a6baf415..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 270813 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
a?68$TWLysm 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 diff --git a/docs/white-paper/Maglev_White_Paper.pdf b/docs/white-paper/EulerSwap_White_Paper.pdf similarity index 82% rename from docs/white-paper/Maglev_White_Paper.pdf rename to docs/white-paper/EulerSwap_White_Paper.pdf index bfbf7d9f1c11fb3574f5428ee552e503eb991aae..55b5667ad066a5ca999b1a7ce652d077a7bfc374 100644 GIT binary patch delta 56587 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] (user1) -- (maglev); - \draw[->] (maglev) -- (deposit); + \draw[->] (user1) -- (EulerSwap); + \draw[->] (EulerSwap) -- (deposit); \draw[->] (deposit) -- (borrow); \draw[->] (borrow) -- (user2); \end{tikzpicture} - \caption{\textbf{Swap flow in Maglev AMM}. Maglev’s just-in-time liquidity borrowing. The swap account dynamically increases liquidity by borrowing the ``out token" against the ``in token."} - \label{fig:maglev_liquidity} + \caption{\textbf{Swap flow in EulerSwap AMM}. EulerSwap’s just-in-time liquidity borrowing. The swap account dynamically increases liquidity by borrowing the ``out token" against the ``in token."} + \label{fig:EulerSwap_liquidity} \end{figure} \section{Curve} -The space of possible reserves in a Maglev AMM is determined by how much debt a swap account is allowed to hold. The Maglev curve passes through an equilibrium point $(x_0, y_0)$, at which the marginal price is defined by: +The space of possible reserves in a EulerSwap AMM is determined by how much debt a swap account is allowed to hold. The EulerSwap curve passes through an equilibrium point $(x_0, y_0)$, at which the marginal price is defined by: \begin{equation} \frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}. \end{equation} -Unlike most AMM curves, which are usually defined by a single convex function, Maglev uses a piecewise-defined curve, with different functions providing trading behaviour either side of the equilibrium point: +Unlike most AMM curves, which are usually defined by a single convex function, EulerSwap uses a piecewise-defined curve, with different functions providing trading behaviour either side of the equilibrium point: \begin{equation} \label{eq:fx-main} @@ -145,17 +145,17 @@ \section{Curve} \begin{figure}[h] % 'h' places it here, 't' for top, 'b' for bottom, 'p' for separate page \centering % Centers the image \includegraphics[width=0.5\textwidth]{curve.png} % Adjust width as needed - \caption{\textbf{Maglev AMM curve.} The Maglev curve (red line) consists of two sides with separate reserve values $x_0, y_0$ and concentration parameters $c_x, c_y$, allowing liquidity to be distributed asymmetrically. This means liquidity can be more or less dense or concentrated on one side of the AMM relative to the other. The exchange rate at equilibrium is determined by the pricing parameters $p_x, p_y$ and is fully flexible. You can interact with the curve \href{https://www.desmos.com/calculator/gzwmvbs1dk}{here} on Desmos to compare its behavior with traditional constant-sum and constant-product curves (black lines).} + \caption{\textbf{EulerSwap AMM curve.} The EulerSwap curve (red line) consists of two sides with separate reserve values $x_0, y_0$ and concentration parameters $c_x, c_y$, allowing liquidity to be distributed asymmetrically. This means liquidity can be more or less dense or concentrated on one side of the AMM relative to the other. The exchange rate at equilibrium is determined by the pricing parameters $p_x, p_y$ and is fully flexible. You can interact with the curve \href{https://www.desmos.com/calculator/gzwmvbs1dk}{here} on Desmos to compare its behavior with traditional constant-sum and constant-product curves (black lines).} \label{fig:fig1} % Useful for referencing the figure in text \end{figure} \section{Conclusion} -Maglev enhances Automated Market Making by leveraging just-in-time borrowing to expand liquidity depth dynamically. By integrating Euler’s lending vaults, it enables market makers to amplify positions efficiently while offering a customizable AMM curve that supports concentrated, distributed, and asymmetric liquidity structures. These features make Maglev adaptable to a wide range of trading strategies. However, this efficiency is not without some trade-offs. Swap accounts incur interest costs on borrowed assets, which can erode profitability if not offset by swap fees, interest on collateral, or token incentives. Additionally, Maglev inherits Euler’s risk parameters, making it most effective for correlated asset pairs with high loan-to-value (LTV) ratios, while volatile assets pose higher liquidation risks if positions become imbalanced. Despite these trade-offs, Maglev represents a breakthrough in AMM design by repurposing idle liquidity in lending protocols, reducing capital inefficiencies, and optimizing swap execution. By catering to professional market makers, DAOs, and algorithmic traders, it positions itself as a powerful tool for on-chain liquidity optimization. +EulerSwap enhances Automated Market Making by leveraging just-in-time borrowing to expand liquidity depth dynamically. By integrating Euler’s lending vaults, it enables market makers to amplify positions efficiently while offering a customizable AMM curve that supports concentrated, distributed, and asymmetric liquidity structures. These features make EulerSwap adaptable to a wide range of trading strategies. However, this efficiency is not without some trade-offs. Swap accounts incur interest costs on borrowed assets, which can erode profitability if not offset by swap fees, interest on collateral, or token incentives. Additionally, EulerSwap inherits Euler’s risk parameters, making it most effective for correlated asset pairs with high loan-to-value (LTV) ratios, while volatile assets pose higher liquidation risks if positions become imbalanced. Despite these trade-offs, EulerSwap represents a breakthrough in AMM design by repurposing idle liquidity in lending protocols, reducing capital inefficiencies, and optimizing swap execution. By catering to professional market makers, DAOs, and algorithmic traders, it positions itself as a powerful tool for on-chain liquidity optimization. \section*{Acknowledgments} -During a security review of Maglev, Chris Michel noted similarities between some of its underlying concepts and BlackHoleSwap, a project prototype he had reviewed years earlier. While Maglev was designed independently and without influence from that project, the resemblance is significant enough to warrant its recognition here as prior art. +During a security review of EulerSwap, Chris Michel noted similarities between some of its underlying concepts and BlackHoleSwap, a project prototype he had reviewed years earlier. While EulerSwap was designed independently and without influence from that project, the resemblance is significant enough to warrant its recognition here as prior art. \newpage \section{Appendix} @@ -248,7 +248,7 @@ \subsubsection{Unifying into a single curve} This gives the final equation: \begin{equation} - \label{eq:maglev-1} + \label{eq:EulerSwap-1} y = y_0 + \frac{p_x}{p_y} (x_0 - x) \left( c_x + (1 - c_x) \left(\frac{x_0}{x}\right) \right). \end{equation} @@ -259,7 +259,7 @@ \subsubsection{Extending the curve to the \( x > x_0 \) region} For \( x > x_0 \), we construct a reflected curve that also passes through \( (x_0, y_0) \) and maintains the required derivative: \begin{equation} - \label{eq:maglev-3-inverse} + \label{eq:EulerSwap-3-inverse} x = x_0 + \frac{p_y}{p_x} (y_0 - y) \left( c_y + (1 - c_y) \left(\frac{y_0}{y}\right) \right). \end{equation} @@ -272,7 +272,7 @@ \subsubsection{Extending the curve to the \( x > x_0 \) region} Taking only the positive real root, we obtain: \begin{equation} - \label{eq:maglev-2} + \label{eq:EulerSwap-2} y = \frac{ \sqrt{ \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right)^2 @@ -309,25 +309,25 @@ \subsection{Invariant derivation} This means that for any valid trade, the resulting reserve state must lie on or above the AMM curve. -\subsubsection{Extending the invariant to Maglev} +\subsubsection{Extending the invariant to EulerSwap} -For Maglev, we apply a similar principle. Given any reserve state $(x, y)$, we check whether it satisfies an equivalent invariant condition. +For EulerSwap, we apply a similar principle. Given any reserve state $(x, y)$, we check whether it satisfies an equivalent invariant condition. -From equation \eqref{eq:maglev-1}, for values where \( x \leq x_0 \), the AMM curve constraint requires: +From equation \eqref{eq:EulerSwap-1}, for values where \( x \leq x_0 \), the AMM curve constraint requires: \begin{equation} \label{eq:invariant-x1} y \geq y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-x\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{x}\right)\right). \end{equation} -For values where \( x > x_0 \), we could derive a similar condition for $y$ from equation \eqref{eq:maglev-2}. However, a simpler and computationally cheaper approach is to use the inverse equation \eqref{eq:maglev-3-inverse}, which defines the lower bound for $x$ instead: +For values where \( x > x_0 \), we could derive a similar condition for $y$ from equation \eqref{eq:EulerSwap-2}. However, a simpler and computationally cheaper approach is to use the inverse equation \eqref{eq:EulerSwap-3-inverse}, which defines the lower bound for $x$ instead: \begin{equation} \label{eq:invariant-x2} x \geq x_{0}+\frac{p_{y}}{p_{x}}\left(y_{0}-y\right)\left(c_{y}+\left(1-c_{y}\right)\left(\frac{y_{0}}{y}\right)\right). \end{equation} -These conditions together define the valid liquidity states in Maglev, ensuring that the AMM remains balanced while allowing for greater flexibility in liquidity provisioning. +These conditions together define the valid liquidity states in EulerSwap, ensuring that the AMM remains balanced while allowing for greater flexibility in liquidity provisioning. \section{Disclaimer} @@ -491,7 +491,7 @@ \subsection{Invariant derivation} y \geq \frac{x_0 y_0}{x}. \end{equation} -This is essentially a test that valid states in the AMM are those for which the $y$-value is on or above the AMM curve. Similarly, on Maglev, for any point $(x, y)$, we can simply confirm from equation \eqref{eq:ce-x} that when $x \leq x_0$ we also have +This is essentially a test that valid states in the AMM are those for which the $y$-value is on or above the AMM curve. Similarly, on EulerSwap, for any point $(x, y)$, we can simply confirm from equation \eqref{eq:ce-x} that when $x \leq x_0$ we also have \begin{equation} \label{eq:invariant-x1} @@ -510,4 +510,4 @@ \subsection{Invariant derivation} \end{equation} - Maglev is an Automated Market Maker (AMM) that uses unique features of Euler lending vaults to \textbf{mag}nify capital efficiency using \textbf{lev}erage. By borrowing assets as needed, Maglev AMMs can extend the range of their reserves and earn fees on trades several times larger than their actual liquidity. Under optimal conditions, Maglev can achieve up to 40x the liquidity depth of traditional AMMs. Using the Ethereum Vault Connector (EVC), Maglev enables market makers to efficiently borrow the `out token' of a swap using the `in token' as collateral. This significantly improves liquidity for swappers. A novel and highly customisable AMM curve governs swap exchange rates, ensuring deep just-in-time liquidity in the short term while incentivising balance over longer periods. All of this is built on Euler lending vaults, where a single cross-collateralised vault can provide liquidity across multiple asset pairs, dramatically scaling liquidity and capital efficiency across DeFi. \ No newline at end of file + EulerSwap is an Automated Market Maker (AMM) that uses unique features of Euler lending vaults to \textbf{mag}nify capital efficiency using \textbf{lev}erage. By borrowing assets as needed, EulerSwap AMMs can extend the range of their reserves and earn fees on trades several times larger than their actual liquidity. Under optimal conditions, EulerSwap can achieve up to 40x the liquidity depth of traditional AMMs. Using the Ethereum Vault Connector (EVC), EulerSwap enables market makers to efficiently borrow the `out token' of a swap using the `in token' as collateral. This significantly improves liquidity for swappers. A novel and highly customisable AMM curve governs swap exchange rates, ensuring deep just-in-time liquidity in the short term while incentivising balance over longer periods. All of this is built on Euler lending vaults, where a single cross-collateralised vault can provide liquidity across multiple asset pairs, dramatically scaling liquidity and capital efficiency across DeFi. \ No newline at end of file From f37a817835137274a74b79ea20ff8379c57cbfc7 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sat, 15 Feb 2025 13:08:07 +0000 Subject: [PATCH 107/312] fix: cleanup virtual reserve in derivation --- docs/.DS_Store | Bin 0 -> 6148 bytes docs/white-paper/.DS_Store | Bin 0 -> 6148 bytes docs/white-paper/EulerSwap_White_Paper.pdf | Bin 338838 -> 341616 bytes docs/white-paper/main.tex | 234 ++++----------------- 4 files changed, 37 insertions(+), 197 deletions(-) create mode 100644 docs/.DS_Store create mode 100644 docs/white-paper/.DS_Store diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c6ed3bc813d5c2fa54f333e65c71a4bece1e61c7 GIT binary patch literal 6148 zcmeHKyG{c^3>-s>NNG}1?hjD#2dgN2L4F`eM1X_>iXgOC@m+jc#t$K#E)*0rXe`;Y z>-FsErZ}Gg*y{cM23P`^(;e~YVQPNvKCz3+7?I99cDTkX?&!No_4$Nz7x=&C5X)v#9lZgGDEYZ5|e5*Vp!6dZ&lX|hs31AYWT2vvekrQ@pRtbq8!!} z6{Ua_7%Om@+okvaTlx?4|Cpqm6p#Y{N&%a#H|rH&se0?=<-FH6`j+lBUvxLFgTfH) km>BJt8*j%~QIvJf*F5iqLt@aG4?0ml1Fnlq3jDPKC$Z=ikpKVy literal 0 HcmV?d00001 diff --git a/docs/white-paper/.DS_Store b/docs/white-paper/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0V{m0rw*?y8c1~>Dw%xI9J10iRJn4>Y+qSJvI=0d2`1SYQ_vgNMch&wecdb3E z=2)v%jXB52Si`!##6qW1m6T>;W9CAj>U%EyMBv~_MknInWaDPz2C&Ei^a1RwygUF7 zb{>EsfJFts$p&DN0`T#&a&rP$lmWZ|7EQpv)okos$tJ$wyvduS;C!iUL%5)OI%qzi zoRfv6&%YcTJpa;g{3nB)la(`ogA2e4PzSK6J3D&-IQaf2(6IHh1h8|m0$5btEWQ3G zDL3H%^RUQC0`vvV_{`bOIk{P_thhM&%&p8#IoR1PEx5TjEZI1CIk+r^1zEYQ*x1>D zY?fT+rWTf*X8+3J;^8(mvtTu|)d$?JeIwJUFo10mf>{^?cnV9gx zlW)w0$&SLXo}p0lgvj>d0@Qc#BrBtXWmi#zWrKZ_ zn&=At%5$GoLUh{&A(1&WRLzb7iy6`l;` z-yxH5cJi=v@^A-mvZvO=vtY6R51Q(h?#`ZW=Kq0{j}?^D4N3SPB!S>`kes~SsR9TD zz$@9kH&+iLfvg%uM>|Jr)Cuhf3RB8qEIzVv{JGE9k5};TDW?`H5Coz{3pO6WZO!)0 zy1|v_y1~A`AAb(2oOftO=;^s#(@LrmQLA|6c}$IJzL)K#l zAItK@7#-+C^ zGwIh%DgCHkb#0M5kSy)#qdVyT^=!V~H-AYUJ;YnIp;Pv99H?DAsg!;akV5;L(ih%o zqZA>1E6bnf@yYA&=4(J}5b@Cqb)q^a`#TP9W%=K6+cc=v3Fqy}n=IGUgeMcPMPN_W z+Z^XMQZLK4QD`KNQoK_8SAvC^-U3JiYr(RRC5*z*Lfj0trfYM(Pn|I zYpEi&M!JG2Ppo}z%_kKeUG!yhj$j$}jDh)yo7y_Ew(V7=2l6!Y9_Ontuhyp`;&W;K z<2BaFw$)~RVq)T}iJ4Ks?cvPDHK2b}hpx32Mt~h5!`Ld*o1Zo8R!c6a=5EQ}gGLpP zy|85YK8XC2wCG9>R}Nj!B(})bmS=&-23gZ`AUm2xoP4VqA{(Q)*0nAFcwt408m*(| zhESVHdqup+o$Hty!AF3zM zg;mIYcXAbM()$`g~`<4g1= zM-!ko-69ZFi+6Hz9u9o%FO8Fa=3OsxNS+H|kRBc2_PUGd_<2a49_8|b5i-Lf9jItp zf92!wAfOY=c=`Pna1@Khx6NIthaj*Wnha9i||`n-QyStV^h_gwBB z23kKyxppvquvFNV*uKX7FhPB@QX0Fhsv%r)E6jG(gAIxbw+C+376@TbOfm}zC+DJO zM3j}VI0j~i62P@?FMf#G{+SSvOq%-z`TFdsVNRWvQ)+oz!@lD+Hj>rRR^vi{tGe|x zOEdy3^k<12APFZi=_*Ubx<&9Il%~navii}m#XM=U4>2?~jmzMzKHQFZ`l7rkLs3`c zbhUamIAsruxC8`1G#4L8J#XiV2dCp@#_A8UczHqctJUKUYNgFkjSs-(FV&`Nl(s*j z7+_N9$SwV%Wr3#jL!dLm6cI?!8sTp$@=ls%Ffzm9T=c$~&6#w>*dks*fW0_`L# zEwveL72+c|q zK?tm37?RH8L=<5g5zvBOc}QRKSM+fXfbr_nmFQB0h|}+-xp%H_AZ#qe|I|RJAFsY_ z?Ot8TaH1v$cS7}u3EP(g0jtrbKX=xmy1Og&wYdHIQ4p&A?N^f+KFfr;`Cha-w_Wa< z_W{sI$Jj*h+nUu`9O+|F>$DuX{0}!Hv=qsEyQ2J(N2-%kJ)E?Wr^S0~x5XO$myelq zh|wUlj-C>U$h~ybF$=yGq=fyJQ#)=*MR2I#_~`1K;?PFau$6~+z`Z@XvFO?2mQ}BA zrQ3e8BHmLA5}GX4tCx6roGJq4pVMsw3?JZe?A{r>KMJzC(rl|w`Q-HZrS03!IOcT@ zhL*Q@Q@tHo2yI&a3_Rk#Ei-)U^8n%fkm18k~f`n?-5Z>NnDITC5 zR`{aZev^w{3yQT+uB7lDS%6nY|4q222)V)P=LGu5Mqm}HX=LQX^ca5Ty%xdy;+H93nCF6R)tor$H#M9kB`9;T=u*raS1)G|t*?nyYGdQY>50!fLa=AWaKchI4# zg9c{2Ge2~ue1>Vx3RLps!gX1ZV>No{7?09gzV_UfKGe0m1F#L;8&1AC}8?B+wRVK%mn;iPPX(sxmI==EQ@=y*7KK`0+*L*C94Kx!Jo_PxT1jOvImgQisYlh--S8d^haZwpl?D08*H zJO!*^w#5*$Erj4t>JVbT*YbVtrB)`$kTmc`VdmQ2{D>aX4e!2@qpxssnK1cP^I+LF z6gmD(?nS6?cO_}4Dh_!DdZ{?wRVC#dkK(fC^qUwQp6pzIZ0?+} zhkNQJ(rIzutlO9|Q5yGheB1@j=U(cz5B)xn=pPNh#>x;VhJ6VsN)mSxK;^TO|;L{6;Pg#^+r-;jymg* zbJ##(zYL4FEhadIR1oWkSvHA2%}6*2{6$x5;s)=ctd*L;QZxOSsv-?qxwWUmFW)d4 zFU(GPH%HYGaS5>i=4e^o7NrZkrz+x93nRS~OCekB#ZzjD{YLabm8a(dPi0Z3JF~8; z(3~cX9R{U=Y+Uzt&lBzuSq@|C4Tz^GEy3?}liUx=-X|JZgA!^*eLDTV?0Hx}aXn(^ zElp`~dVj~d9*I4qj+^__agNcb2mXWt>ez^3RDJwrwl#48THjR^mT&Vpl9ccp7~*tP zRg4P-DrA@BtW1Aq|Jj~G_gdJhd1O)1!hTH`C22o-SA<3&ZdJ$ClxeaV8pG$5ZxL7N z13iUl4nT4#+lpZCcxQ{LrXnK!<wmq1h}&^raw8(N4!TFS}c{)SPR zMPzHNP}=DNRQxk6jNPmhTCt*0Gf6O0&dRfkrOa^NuXC;}pJD3Fl+j@&gKXdQrMDD=QE@^W6Ku3p1 z4jdBQySydv$CbfRrj?x^k9*4WPVR~rDqmjtSn)o99%pZRdXfdQ{d4x45iB1RAEfx) z=KaTO^9m94J4G$YJYTjy+9f^=1dDJ^uTgrv0mCbeTc#mcAQHwkVVkP3d)NAJ2S-NS zQ1pwy$DJDnq)?zp)ew7xh!d+_<8?W#CniyuQH_1wl+WbS6wiv!;f16@$)`UqszwAM ziPD-Sjm56V{jh8w-G|78FXxo?;}9GjcLi3}Er=#kD3edMw&r)aRH((2fZ>Mbq@eJ_Lvc9Gvz)A!XC+^d1B#$`G8k z338r_4b)}=PSd6W4$fx)&H*yTfTn4yHw1@;{MRo2H~4J=4h;#;1v)YZCxhhT{qMj7 zs0`ryH@lFwb#wOs@bIwzukk{QzP>vaUt^F+Um?kl?ffba5IHyZpb65n%biI-E1@7~ zDQjS>tN*4W%%3&qpdXdzot|6M^`>p|>GCD_rJ9xUN8)PO%s9O+6{?-L9%Tr12oZ#a z<)?_w2ud!_h~^G^hNi$82El(E3Zop+Fj^d7LLVA0RsQ|kf)w@wh9vI9D|sgQi0D;B zWi*m$)%WkawzLv6A(4q%=w=1grCw%Z=(-RU`Oz2+SUD_(%pO_`V8fc}objqQSK{b~ z1x&8u?{?N_!e~ou*lalbi$0nwG0|m}tnxZi>JbZ+_{pppnM%M?*4$A!%91kI6b40r z-^5b7g?vcua;BLnIURM$pms(kxly@@ZKZmI*3aR5BW+zsJ~=IdP`ye#O<7;HtG^;6M9amM#$n?jEbMbYTrFj)UX{HJOb(zb7+Zw8M7U^9S|n18W~~n`v_dkOO*NDtD;7mIRC@rbX^SgN24tiJ ze4MDBR-_;PDEQcDa3lDyfzp4$+%pbW960ii)A_K`dhAm%8Jx&MoJ!rl#RY8DG|%Kj zuTtaS8talfqU(oz2ngZG*&)`tp{eu>@-8Q=FfWw8nLyXC=R_dZ*ZWB;Bg>qKQSIDs z+%NjcgBL4}I+pME^`DKrRmOtdI^Fj3DA7<>bFqa1+Q4m-#oL*?07GMkZ{oecj&(+R z*0Hv&+1hij)uo)owI^J~NoK0Ds5C`T%7%>G6I}-x)$bCEXSKyZc~@DvVWyk9+KL-P z!!()LC*TUqUf7<>u?ME6b^Gogxa2R{VYxSQo>Y z@F3&08^Xvy^ET(~O9u5m(Nezy-}PDnyn*QZGB|z zU6Zp&(CM)kM~yrJ;-?#uT-+1CEO1#RInS2O`=E|>?2p_s=Rp^Fm zMG6DnrB6`X?dFq+&w+{GdvyJsgS1F%%2i(O*Q^tR0zaSMRE$;oagevaIE{z8saR1i zs+ykm-J0~=PaV0&WZ}+^CZ67A+NOTWs>$gEb@+KU@ahMa#}c`>i5+9>U+b-zc4*jm5vH*%p)b zf%593NCjr*nod-VdwgI%9@o|E#DyrlY~r_vl$*#E8_i2Md>`K@9{g#lb3=OG!-Mvt z3+z}VtWYHc-d}DP&OXYbE=5-25gLD20DxUlc{?cpwkXZpsr@1B85@Qg_3xTy{%mU3 z@3kE1p5EmLFTR0X8BZfk2TOU0UqNn<`xWBqdcy4hVO-pk>=Dujw-e*PHgAZh9-ID|1h9bH$ETsF=jbe03I8+rph~sj zCjXTtntd$+@>>>~sJ;)k$v^+_QL0frew()Z6W(nn1NHgzc_EXSH)wD@3T<~fE4n!p zzd7_T*Zc9z!d6sbbXICxpu3U}FcDwx0_J7|GpLGq?|J2Js3e*A5VN59s&`G+YhATNm zNk|r9Y&?xfMo?nDN%n0utNx?9khm_vHqvnic|AQBS`f-5c@z%PK^NS!3*tDJZ>Dow z{#m4c|5^81MXxHWcL`4mAf#ls$+H{MMy3p&K^Ux8>ahgjQoNEtv7qmxcB9ze)dDVW3=S7ZeGrcq1n=AD0-P5GTi> zA-Ty%)tF7V+*4`A8YF%;qnH|2jNcL55Inz39%wJ%e#i*nExD#e5;$Rs`J^ZnZ51hF z6Dq!?dQV8YkPnHPX>}`Jk3}yvEI1>5N-@j1CgcV&^(f@|04{3-Y)uokCtqNqgND5d zXb_h)g_FTtz)7%h<5Xb;Wc(RnPGY2uu{LAa4f2Cws~fBK_+3<7eOwOG};V?fNc2i3q~M5ckxnU@Wp?dW_m~m&5GwSw-kz zlk}Mo_YBO}@Ot8hgL2`r-wRgf&ttW=_2oS5Y-L4HRX<+@ax;rb{6tQMc9SHO(S{_Tp@5G{?7qrSVYfj?jHLkVKh0Xb$U+*~js`jGtB zrp&f-%y0q;7q5#VVoh^<6NTqgO=NZGCehPf#0q=Fk3#9@dJ>oh^lZJwpNMea(uxu| z*n%oCxMu1|z+na^4M_^Ov-@_3b*BKLE?O)y+OmN`Oqf!>}W`W=lqxW1hsqrI4xJV}E> zNDbhL?%M0a?It63n#n&d4FdhF@VnrdZf*JcjY&yAaDdkpNu|CTO8NQ+z0I`yZBdN~ zvuF&_)Lt6>T2YkRPq=7XVw+=f;5t>^{MZ38F zq&t(D#r|pJE>V@0v&5&SCH##QzP8;qk8B@y*?hJ5eqgA zaous^N6H4VCd}>vGN?ub;BY9HF^o|9iTQd;O~w?!m(cN^XO^il4@HL_w-^=LhPtR3 zek1T#dusL%H*)bmB|PD6HdX8_MsH&^{sU!*Y*y9*C(J`nD%c5ujKbZllC$m|*n-6m z>}dWLk=)7`rll&ce8k8e*RMg#?sRBC!UtK%P-lX^LUy@jGL~!8IvXDNmn@}Q&_4A}^zh%y> z2=F(U`<{cd085sg%-q4XWSjriv;tNaXc;@=SV&gk&M2E*0zJ|vOK1*KQ0n51b81Sx zp@%%u!&@4{gfi3plDmf!P00wPp)mzRbftrqg1K7l%8Y#WRX-N%thppIv;&r0-cy&v zS^DZTl!!_`0_ZB?h+V}aLHA(K-?0@2ePHBQWd-L6&#I5ZHF!LV^Hej`J;XnN?4AP$ zDXoM-rT&1q;VwJ8HGg^X!3`&aA;q(Gf%00^Z`+jutqzWCCB$X!4iWM8+*(`Y5VArC z_v5!>zIJGiBc*NGA-*VC)q;QCi!tAlXWr0!dqsUqy`rTJbmYxX7-fCGbVj^r#s!El zFwTT91~sLW?b+HFe{s1FTAEM-i|(=q8D??YuPK?`gd}JqPZc+9hf@vO8sDBf5=Grr zBK?Ct$&!ZYEUq^OaES;_^)CuIE*eC31Ako7e`;3TaSMGxxQAH-xIqx`yhs^}gfd}{ z+_B>*RI&u4>3g|9*I3m9gWwkCQ*(cC-}q%a+Cn12MpRC=@g(p7rA%C>Jn{lN zAo1-@A{~_;7`Iy8Q6u?|eBp;FDt@(%q;L<#hQ)Mi9lW+Gt*3XUbuTP-OO-rESyfrV zDiO_k?#7dfcumF#@eySBI>9m??{tv7kfm1soq+a3EKQ5y=`w`NrC!i%anOU!BU$T0 zD{x@QBemi36nsn&%KoJT+|7Q0qlB92Kz+Viv>-ZQbe6L~G;7QJMUOFY{I5%oLk*|Y zPkTNAC7zGG&}8Qp23)7N~6gA5Go zrXKD!Ue30T%3cc%(x&d+ebs6wSELM$GC)s$4X>)TQ&nynPQo?7i_Tx~4fJ(WEJvhA zYxi3!yf0L7zqED_ZTLj`=&J>vdcB>W(z&_4b6BqJitTv0!zr(Fnn{`du2249due(( z@p}~ib7$3SkWFlmjmd5V>v%p_cf_^xhfCq4MCpaPD%7p=5ACF*r|0;l-P5oh1~$_q z@Md*pW&a{A$f<%D2zhl|Fv7W*pdoREgu*aqSJ2HvHr4~^H(Zblgt_UX!M1c>O;zLB`0b(f zR2rbLDxx3wDOlEV*C1%T_Mp_m40>8w@nSb%I?>5O!_`2W*Bu;yFgA$=9%}At85GnAy(S7L_WHz3EeNNHtUpu0EVI#*c{p`Cyw(`+9 z!Jkp?H853#(X8JnFAe-$2n8OEM|wZ)E%gsy(~8nH2xrwQfcIC1k0)cQ2~ z4C>ijCf#Aduj)XT?A;oK9!LK}p*$rG#NTGdkH_QGy+qV7mgY%o0A6~jOUoNLr8RWQjqdmb_=i=D z3b-}`{jgG`cQyntxabt$_hu*DgX~6!gq&F_oN%zSr3vKtCky?opQx#jMGO|54g)u( z^(JuJOg#wspQEN%kdyD9yNO@iP2=4ziB@mbR$MCI3i$oYew3~FK1f>>E5~)|=U^R* zU}~qDO$>$!D%j=W;;!kmJrZMNa42LypbR_#1Ff;vU}T=Ws(<}av7q!OSA_Q7_Xe)VIS(XKUjxtQ%nDz&f2Xw6d|CIuoF@RVUyQF=OWW&lT{5IU3$9!I&Nn zY!XP6lijVDE&}5OYk*`0D@N)63^zB1I87|ClHNqmB9`1fTAoR}ZrU7Mei8J*bpTVQ zVEwBu(Hk8kbxZW_@4}j$*opG8@G^WaEC#oPL>VJMiLO}_C5TC+m<3--ylaQ_9IV1h z3`SZh|80?aTRL+Ycl0VFf;AN%xkPRbIFT?=e0(@+vgmei&f4vGXfPeG%_9KHN)EaX zFvvEpyV%%xPYLOIk4d4z{tQ{+VZD%c#9nWpX2*f0+eB1<8O;apLAX^w@r;W#y{QB^dGDvg>o)c@Sl zSSq9r$YRvVt0OZu@8wRm9Sdz`@cbG8(_XIp$&yx0g1Py6(YzW-`Jm=(|NPLLM_>uR zEVc2cD(MSCJb#h{v|tX73C{hW`4Iq$osFIQzmAzcFK{B@ww}K8)+k2MP2IPAmMaO6 ze;-jZ-Da^IWU~$0378Pm_t1>hRy$oyDthJDi#Z;J#np%un<=Rfa#gQ(qS-(zYgvVZ zA0~@XrM5BC3e-%ZNA(zrRc7pql|L4ntux)4^#oUTZLsV8N||c%actwK@urF~r+xIO znifs8rb9D;9zQq01g$fRPI4@nrK=Nsm8z_FmV!)@|MFeJo1K#7vnG8n*81*+6{84t zYA4o)1g|WRK}p%4Obg}ny7xUAR!$(FNcIqHQtiaCR5IUjBrOd})E`3$ro0XcEzEKf zPmtuFE*=nSO`k*`f@B9rGstbRMVrZOu|jKF0>@SaG~2Y5Kmt$dUSPeN5J%5I9!9j{ z5yxzV6`d55r=S9_ck+UlWRsK-<0;|C13MV;nT`9rv=y zl3*p(ZuID+n%8`!>fCT7SIGY66F~)#x6`-}Jo);7SgiLvM3??iQ>yVtU%Fcs7gs!! zHe5m6CydnKwEhGx5;5E9kDnyW7>m7J_va%D>HxuGLYj3d zfw7iV8yVgg%%s=8HM2MCSFssPk*r1RfkfWZwBZ;`YhEJm-tj8W(5RG~Xm*+3RuO9x z*LS?h7;c92;YSdT z>lPeXhn6x6Iic!+=8?6m?fV9FYJK`Ej-gJzw!95hmYS+Iuf8?S4@(CDjaH0&AcKe_ z-=^&0(p35;oem9wNB;T+%xw2%V89|r2GM~&f!Rs5>xZ~EY$T31td7+$YFCMXwmKia z3UsBdy=Ua2uZEZ3ZFRbL*9U^8EKSa>!d;aYFZUu+Y_-w~x!Oz3ySS;ke1s)t**j&n zTq?1a$vcVPFCOoFBR+h4-d~@qfD=b6SbeVy;s%lau`RSAzYVEvG2H4CY>wSJeam#qE%VS76zk zgZ9c-@F4LmoDv(nD-xUcPw6?P&P^Gc?>?QG2DLabiIcu6uZ_gSERB{LGpND{hsQDpC)G_ad*$eb zGiN))U6|BZ@Yg26=6pE;XJUdCL-P*jlGIRGfLYGuOLm=ADiypw6LaiVm0Zp-mH3fs zqxtfF0*r875)qyrkzlwO5c7ZrHM1#C`!#DKV8VIwq8Sf_O{&G?3mc;bNru7B48>7Tjqu6VJVX>-QY3P-=U$q>O3B0LMENQd}FlT)F@;DF>a zlXe_n>Tf~BoI36RIDt*#FD#ZE6ESaAmudJQ!t++8IzBlLr@SrhJI2O-Iv~-U|8*f> zg0&#(Ao0l3YQgInFmP{CG@W|xY#Adr$0L-^)p`BE3sEkv+5;mYU}EXiL~rUsb#vwQBzr_ijH`11I9iJCzD<&Pjt0r<1-F$l|YQamSpR#8yC4wcAen z%6_@0tJU30$Fk(E{&A8w`vu@gUaxbWpY}}qlh!8T+ZGvh5SHMPs4iRgigGYW3c-=- zo-1RHN--6k0-MFV*M2Yay#dRH(IkNL)!^sVvhdz8{}a?bBvWU?nkG9%>q>hS*4doa zhO)t4xLH9qa1VWCkZ=h3DZ}OsvNA$uh4m}c!*>vp4#neuAh!e^!n!3LuT;_4>JgB2 z+Kv?{qm0@Zi6@OzTwQo5{Y>m9G|mYV14slQa>geJ<47t0MoWOM+VKl}syA6dXo3ig z6z>p&UwGUnVxk-+KY$@|2z;SX;d8{skkVE9P1Rlx#9IXr1^&FVnG46`EzU_1d(&$M z|8ZY@wYeLlbRC&E0KRW&jP-1$5t7&=WQ5u(Z5iv;b+8$`J-ZpzkUsxXo?N~#KwP)r zcVT%bF|<=O^xW}1Uzp+=S;vL*RaTjF>+?rHNc#T$1GmW~-#JhFL|NC25S#Kr^iaIpR_4eUx!#e0hzqwh`Qw)K7sf$THv>Y8kuJMhY%&*MVqQo${sYV$af zoH*tCm2)2lUJ^BxY(~npKi}m54j&#;@W8aQ6+WG?qzn;-cq!apddkx*-Ewu@qNT&I+mrt#W+ZaQFBPPKFs9)#VluE?_seHSfLU_)zIr2=WXWHN>^| z>lsBUpexI(t#+=O_gq;94Kmwg%M@-qTxc0{w~(f@1np=`y^TS-0S}*tf~BHVh$LZ7 z_OmVdPw#pewMQg2u%{+0pdQPxH>AJ|BPMZBErBvj7Z`Y!3piW}OB8H`G>hnSfmIH-!ptV-3;e7+%YA8VTW8TwN_7FwEl7`jJ;pX zN}>K6IIP*eXK{%U0Gx)h?~BPq1WV4{l$XTu;rM%k(m!pPsi+k0l9}rn#xb|B$X-kQ zS-eO@yb|IZl4GTaFO>I*Wt;X~SD`TGA{~;%_=A;Lw?f#tgr)oakFA)MzKM@NE_!#HZ2wNH z$u{xwseD7HIo@F^Hc3vq5JxN7pRZ0iw&Wc^P;fp~28_fp^&rH1zGS5{5bhL{A} z`@J#0cJJ7_AJ<}3V*^=1v@@!h~1(0OXx#Yc$6!f$rW2B(ZX3ZZ*WY0 z0HsJ}%|B)4X_ZD9PcK!1rCI0?ep7OGVqQA31b&Hd25rr^V;*83;;0hXCHwsqFq=r) zV6%QyE@aQiRwO%Gj)^oa@f!0S=z|mRMgmV%o^Gy=KRQpU#Ag#gP-Q7T*Gc*-9XZwC zro1gK^jz(`&9!X(`eL5lpcXTmcO;o03G|9x&{U?{IdSZzdo3J6eUfLqMiBggCclUd zol<$f)M@|<?mJboCWxT=@UlW^p{zGEcl9#W zwFzk=H6xqoeUG|%1HXBw90-G|P%4*f&dt%09UAh5ZVc!R2l}>*xT6IaYbixp1CiFN zoTEo2G`^J;d7^|}PU8w3J2usm=(^)S=H0Wqwa+rR}sU#6t)XPeIF701@<#kncK4&#CkOsae{ z;NVvThK0bgRd5x*)yA0LpJrtj<6fxP2;QyK5$3)xgF$@=C$L5vquhg1!T%&9ynl0< zg3<8T*m3GH|JH#9E-{VN0M!)m_^}73i~t0q=_uq754goaK!%Rh+7M@B0?M3rbt0Ny zXP=VUs=FUB3~FDfTli|leNWaPdUK6< zFD^sb5+0VvIDk-EFEdipEv~ynoUPVv(Yra1qZTf{8A!4ErbpJ zJfGVA(F+OJ3yK}gWZ+Jj0dC@vXM`Afu+^P&bElO;%}#c`OgpD)^Gjt}DeQYv%&WAG zBu<^|Z`*M`lqgY)2fkH71V26{C9@#4fnT<=Kd{ zlzLZ^0r(8PW90m1B|%c#Y}h@sl^AsJy7y7!4QD~@yw~rpHSf3e?&a_`*Lnf6?75s$ zVtc$@Q_|~v0N%5@z4k1hEd< zvKoi*F(U5ie?Ml2^WuL;b2x1!Q*zw=OhH&*;x){~A~yNTV5)rj<*OchzIhcF&tjp0m}~ zkylQgb=ODrthMLJSac!fe5by)MvZl8dG-@ z%`v;4K-v5)L=}^fZYSJ_KJUK9oLEMErz&|Q_7BtEaUN{Vl@JtZ&7&w0KEbcF=E>zY zxR>YYUM8*6X&@l<(KEe;c!{nU>aSVGcYmi?S+*;1%2>xV~+D#_!q z32wk@vxPmmuDX?Xx5liz*lWYm;E$+FwS->C8dy=LESzk~Z#QQ*jXrH|K4fqIC3#PO z9hc*T}yetHC%kWUb z`D&_i04r!5{BeBEcl4(1c@v;S@&Qv=V&E#9KD1g6eB9`6cYW{W zz@6|*M`k`+{to1Yc_2@e@f(fbAhQ|8P|GPP0U4{t10?%NnpcSKGQtdWB07uqEFdPh z#D1b>8m|HxZ4JAxgm&*e_Bo3c==L#ka-WMyB~G@-|A{)rsv8lVFYoxGvm+dt65_&& zTtlpVY_G8)vX~}Hh-2c)-A@KqfKq$Lrz@$@Sd5-z!+uW;M|x9H0qz*8lTa&T8v(<6 z;IIBTO=H~=VPH*ab|@c#S{>~J?n*3XU>QuqC_pq^)x@*ZX-?cpwHbF|y? z&T1mqU{}3CT)>Wni%8On07Ly-^)Yb*&)*kARm-2M)74i4t`%NmyoI;qX2=WnrsAkI zYa$kSE(X^Y&kz^kOMf*n-`oYB-WCw(fUuZ7^KP5kLh_8IWSko56=ZL@*YN=w)})8SNQ%R-+OVE2ObvO^$fh@+F zx)XmCVoxz^%4on#O;D*(>TQH?7XrX4Y^HQLa);1j!`leW=492<8%QNL8dQX?o($g> z+)-yOK(g%uojhw<(xmR+^*KOhNrlm)!1lV=_|ebt3RVyYXIUX%U}GPZMm-5& zll425c>;+-aEEiYSpWv>9R#y+R}t%u72y|>%;njkhihzDULW%);7jeaDa`uO;T8U- z@tu|8Oe#{z)iNpf`RX|g{QG$C$Du>q6mH~FcVdx1VuDEprZy?csEA-bkR@|>n1inG za5Eu%=j>7W{+nKFFyB~M#?N)I#>fBz8SV2q+fFCodgxS5yQJ~}6z)3-dmpZC2= z5%~5fGgT^zpb@NZVU!1gb<)c27{7M9is~bkX?j7m!KvK#NSXx&bi{Y764||H`(m}h zelUm>IP#|y7Uy5iUZd!0qF8j~J0h`c>Y>IaF5C$$%0gwdd=RhQ0-GgWbAxS{GgOL3H*Cqcy0}jyOAS6AI zkCpR(-Sjhh`tBF4=t0kQ^F@L!Xrb-*7WXbGw)|IdG*`nMjx;o=&5~OVv}#es30J`1 zhK!=gSd>$Lmr{SySWkCu+=cz{JA*_QGhArlVC2v!}p2YAmEz;!NT zW>?BM9=l%ppZ8NGI1k+n7szt*S4gGH6@Nn8Ey*ePzPg(Skyq@3{5xc?y4zWJ9^b!t zq571abO0Y**H$jN8MGf?`JIEhhRKMzj87idRUgVEsYvVU_JD&G9|g7AN5{E(rZ~bZ zUF>zI9rPkMlUf@E;nwHBu^hp(6lS_@&XfXWat!Na-YY7|qEG^Ma18yW{BZ*6t?4u} zx1-xUq|D@%o!aAa7YBQKjz}4HUI`tyt+(l<11*~rPN3&`kIeH z5h8g$Gx;=dtJzy9{xevv_AiaeB5Jdup^*2BM2scpdHH-xbqF%<3WM{uR9Hhv#8D9} z%>OtIR0dJ)Cjb$9uFtKOFOg+Xy}M=>2hh2McvprDyS7pimz7Se9k(lH+n8c{Jh{Px zLyXtdv4A~TeYwHVqo&}s`BFsr{)wi&B9&zL{sV@FS}m!fRnS?^S)2Y&OX*T?;89PR zpEHU4__^d0>=mQ@A8Gd%>{b>O-naoLH%?vk`x)8w{x;{^A4B6@VfikiVtnzQ_H$zy-!@-E0Q@+nVq<{DeUPm5x_EM)xVzC>Bp{+X=j6kwDmrEW>XTq z9nXHwfOSK)gB}qmLc0!R*U61(Z|ACAzQ;>d2ROEH{o7IzAtU}r%803fPN~8l6R+)0 zbaG}^Y}4b6j~lNj6XTt7^$`Rw{dkM{pj>4BK-^U5kFc_G*F!w|U+l9{h4)J~lU$HP zdBC&$b0S!+I#*TC$goOxVoeLWCGl=ZbYU1#H#BNCwot{16Y0?x0|*pNiE2t2r~BZV zP*Fk{-(SU10Z(~`3KOs%FY3o0O*2^mh8|LwQ_|`+qFMBecKCPDzWIY?$pwa`D&RmPpgn->i*wFunt#1qtG-$VsZQD*Jw(U%;iJgfjPA174+sVY5*tTuk zwr$+0z29!_-P*tXqpP~A@tpJYIVZ$1?DY5X0wC2|Mqkw&lB>yeyn0ZWZ->n%k*j5X zK@lK~YQTt@pKbPMOXG81l}4N!r=K-2%+vo={nyc7d>2t)Rj@~BX=D(xDI^HN*&>ub z@iO^cJ?mpthU(9O2s>~GO?;w)F(E$0f>ysnJ=@p8*NOti3Lhev0_ZZQDqQ7|UH2#m z^#Nbu=`*+tqy(3kUQ8K&aY?+o$_*$@i3L{HCZblvS+W6}!rwo{`=u%Gh))&PK5jHgfiXp<|0;hnLB}h(b})4}WOb42qaqn1<0vW^F^0UPNRO80odcn#quN}= zZV9;lc}}n4zSB0y)mU`pm}gXuY9Mgql2V+5T2_0JcI$dH2WJVV8Xdtdeux>_3@b(+ z%;IX8vSTh_9>bQZbP|>r;Amhzda_F=SQ+koMOL*q2SFq!E$GJuE_S9Q?VH~GcVu*# zznYc*F+8k_)p*2fW&WG128PDYtyU#mtMxnYALM%ny+0^FBxW!KY66lIY-xdA%5SGc ztjSl|AJe;xTk3?D8ayVAop&^@-E}cbu}_$CLSmOy`Pi5{$)}c&jB^kU+;4j?X7%m2 zjvV`=;E{>3#fny<4jO5>Q?sLk7EmTe@DI!u|>4 z+@_2EGAUX(0}#%-l}tV_9H~G>4(fUcsMk1=-Vz5{8%Obq)#KfOP;nOj$ZQ7#A_m<< z>Ly)^VSOvctu-WRcmXc*=r-#!gK5*?ph5c0Sr{ntH z!|+v0h5^!^@4iN-H3^XeTGD;cnVsIz!~O?`pTB9WYahePy{ohKaX|oEy9@#;BM)}C ztCm-a7CeUsE&c6A6yE+^s%GpIlyodwtr zdQu{wvDD(Uz8F@{h9H`ToOoyxvuyZIN+dli{Kijx>q`)VU+rR02dSf&X0rl*%qEkD z;1#oP}x&)u=nH zI|2cm&@DfA&t z@@xvyb~{eh;JRzA>U?Qn0F~6Kbe%H6E~#ru4R7HBjR4;{JM7P}eRAbrE->&O;84Tp z=yW+rCud7Us^G`O;)JfeSkV)|kl7>YS$@2&AaEGtN{5Ql_!zmp5{w0RXi(FRE*s% zFA`_Va0-s-1_@g5ls(;@+3_p!OJnE6zGLs-J0A(XUZhKInQi0FLc_%J)EEwvjV@vi zwX6b*JAM?7Qe`KWjJ$)2pHGl5Zk~6EYxY*69NXYGN}6nrY|y& z9!(bw^KRq?$1^KAtEot+B}%jCxd}X>3NfDwDPpA-JuQ|DezAd2n`X;);rkfLY!-! z964b$qf6lF7dsRDi$3dtW!@h64*DdAZE0Ce+##+L>5%}_14OgjlAwhOtwonmY!MS`pZOKP zH53tj*q*x=7WgK-c%|$d+2{Q{ca@$18do^pohmdG^nFi2w$||AFMJ2#T?^}!CDnO!o383ao5!8kY;9Ls;3zp%2hB|}bti~fHK zch>(D?yeKyv;Z43^Z(>%4t~fa>@{L`{;S--osWhNBF)wy%c!3_mS&Wi@*ea>BHM&* z7;BT6#iylyK6xM`Z|4RlWf55jp!R=0UV$1$3_w4 z;Xw=6^yj;F9q!5R^(BpZKwF|bS8Ih4ws%t_~91v6q&BBzNockpI!V~ zQ$E(Xtie7$AsnQx>gElaS(k6%8bY{$^{}caWV_ikae*d#);DS&s4?|^%4{pvX9zJd zx2fr^Q?J-0wDkcAqvx1)_yb+yt?@?>W1^7^=pAh)^+8pLmCi=fg3%L{l_QX)#__P+ zG*DXfIbU^LHrUi*k+uWYtL1cB$RV#u)MaawitD~GD^JlO2c_KHM$7yqvFW&CKmHD| z)UQN)1z`;-9&7uow#_K$#RKwm>y(e~maBvhCtSk{Tvfy!R<3ViS2Q$@-^r`vsA$eA z$slvB;`tk|sJyP}mE=^JG`Wpc)r74RC2{I`Z8pO7Jlp1T;M|&0<&^~L<$vTyfX6ZW zXc3&gDJ*pK7$Uk%L5jMm0Kd zq=@E~uAVH9+c3drYTWmk!t>tzmOr@B2_9B0ftdw#n(Rpuk68s&OA#_fm*kh_%Wn0Q zMacL{-G|kBbDQaSQ31n08q8)q9Gftk3plD_2j7tN{S_xQdH_?h{R18cM)-XJ2^!^} zNhM`4EUKazVY^g|2R=If@>xuk9L`Nf7dY4)N%N}M;XL9%7(id zYx~jjqO1L>HLP$cYbq1RlsnMv`=f8Fsc}d~$%woR22SPTN;=7tVq#ORCna#)ApRgy zJ6dGQSVons@_>3=LjS7q5`m@F)*ERrUqN?skbB2=r9~DiUdqvW!!AlMG4WWX8^F-) zRP6SuqvCNu2FC7Y*yDYCg1xG7~v=Vs>SNEvrOqt-sLT$%)#Na<_Ni5NL2V|4ZoEm$Zwd8quI4uc9gHlV9 zzSHm@7X!7`)FxDyGLBJ~utJxL0~-l45}&wyA6gIitHwJ|x)pLE%ZqAJHwgI$Vrebi z%9W;R0&~VAlePC^rg?M?DhgcTHyKXTOOESHq|A=3w7YInh=Dk1l@#qD=XE9OFS;_V zeK=7H!1TMaC-03Y-?IVS1NzDLBsbDchmgf;WYF-_Ut+fgsuvwkC-wT;4Qc{`J~UYW z2xq1>B=klf7Kp!D=Xp_Sw6Rg52BN>z9VB7kz`_O4@`pv_SN>FbRXR8|K{3)~kKP~~ zeho@SA(Cl^R$Hh&uSCL>&!p2Hh=GEUiaNtY1O6Jq1yX`XiCj&>3Dlc+=Phv777}w& zKH(B#$7Wble0oCz9vVq-KZ{ho@z(_9IEeX&T;6=b!^h3ppt5U?3F~(EO7b)0gwU!3 z%}dM(;Lw;Co$?YPK02dIX!nHcQzFiLeHMOJnatt3wv8WP8)cARFiQpqVX0(dFB3Sm z0+9BfUT$}1h)*wtrrUEQ_Dj8m8DRrfZg-a!jap*l?jRvhLamj2>-^}J3u^;w>0QdN zLNTGtnn|fal0rW()JyZfm&MEAmLqBDyU%zL{t*I6BIu@qL!Bi*eR*`)dQb461pB(0SGbx5*)d9gsQ=9N7odmh_+km1#k&2 zRCF>@JMw}NkQZ-`E5LR5tn)8QtFU0@L3Uv{l&hwQNgg|#gi10oX^-^VVXqU*PRTw5 zQTW4|@Dt~VnhHF9k(LWbj_o@61$(9({x(8WSpFo(2k${`+I_fFLB9!jIWq< z4|a2@lc6TUIBLp|DA{gXM+u#J>MTG+)a}6Fh1ZE0K3Czt+NHnN*p#$0wK5{ur2kWR zK0jg{9`J0VR0vMleIe#7nL$}0kPasn+RC}fe;;2}{yEN7o3HhTE>g}!01UsH9VhVzN(Gs zf(Z_qP=y4GL(|`=m}Xk;mPzsTwhEZvYwyXB2d#pU6DL z(;XpY^GFYN#7^K99jE6`B zVIsVhEquST@S4KKczZtlolB_8?}sY197k>vm_n>;PyLWU0@a;ClvF%~f%&iMBBo82 zUAK+q_m;vg+lR4yCcWopeYqHto288_Lr_kY^4ICLs%2Yz;7shxsKie7++uF~=Grtr zgKS~=Z@CbG!^he!@b_m(pDghSVfCNA%IcaDgWvzeAaGS~1znpTQVLS&&I&p+X7*xD zO_1Kamac9Sso0?U*D48oExz_w;+nzM+frXdJKV^=@6)v+KX=W|7aYJo5NlccB2eC& zh48yzK*LEeTixZTY8fOd_CZ7g{DOzTWZ!<5CSgQV2ekz(0-q0%#LvD5VgeZ>+gBvE z?GfY4AX7Ep9`ixYKFZx?LU^w(Ps-cw2Qs(Wz&$nRf}co~1lCdd*Q+FS@GFfpX26w4 zJTPd>Qp;eLn62V}5%Ga2kqSWUx)qtGW{bi2dJpAseL8J#Tr2tO!afV9N3?vD$3eH1 zGPd^GiAspr+gZdtJs4RAQ(LAYdy{8YEecaC*03VJP7hl{ z-(2H$p7t-4^=w#)I1nOL`?(#$yBl0)Jh^->FYpw;0DQLF5Qn99`lUZky3Lwjg*zyg zp@O2rJ)2U}A1~ujzBCrFoSoJuW2vnz_%lUsjkjKWo|mk3+llAd;Jv?AD)yqTzpq&g zv3isbQbVeS<+@dFWYUiF=)=typ;;m>^SS=L$EPB;i1x`M1Ovh#UgdB9V)%nkc9VDA zvceXP0vv(pTFd%wnXmuYamI{}GWw~_fg8svX#uF++>#KeU{CQZJRNKi`|#kg2V}3YeMW<4ijMzPjf=-S`HR-Yid@` z=$1uYkz88*9R0k*qHEsxT0ivh7d9dM@8mZPW?{(m2haKaLPJ@++dDgYrhRmBfAG%t zNH3`>GFzaDNMRw2kEkJ+euvy0@(w0N#{2PhkD!$7@0)S6ZoiK?@I>s_sh4^V^89(m zcF|JzIX&tI&DQxL?^5`8biCDf_Y)oV(t;=%)C>YW`EnT?i;VR@@PO?<-x%5c+fX)HBUQINHL+M4>U)eIYN*`~Syoh%IkLA2SKYVL+Rv8g|E{dVQ1x%E}7os^*K zl-bcXfiM;6uW487c6R<0L>4)GMrjhx=;OYcya0HrZs;)uVMcs-hao%G@UmxDLK-9* zwLkW8e;u`DcYP@%AR9`eS>q5~Jp!%zjwaY&_d<%F;M}?i>o5_-4l?ZJ24Dm&_r%Iw zHW1B}>xV0b%Bq{Tr*t-!(Dca}c*c-+Kf`=u)^D>PLBN(G6!3kBU18>O?H(mu5RvWl zTY$A4FIB-r`(hPIT$#{8VBxM8DqxCg~+S^{;2mFI~(A@tKbUN$u zrez^zTVMGrcvQe74Qk5-(Z(!vJLv(9*xGqh*_Y=T^I=nSGK+Yv7nZ4oQYCDNdQPAb zJF84MAEXunE^4;13^T1p0SePTPyd(5&r@zMw7I=t2l`&KB4k37Hx8S6NdWc_i%ju3 zR4RSlfWk7DyI;wBw<*KK)6kV16DzOq;v{%o4*DT zJk`kjQ%SzUR#SJ9qBKLIWc3u|%RHiBr-~zNtYqxf93&nT9TG z$+OU_GGP`8+vy!LB&j`M62Kj(lS(0ZZcnj4mKxqP=nv&klC&<{QcO?CG`~-mPh@_? zb!>N?JeCB^<-){Lm7K%@HI`@>dT0R@ESuh}?ce-?eWz=Q3Sh5Rd^$+>)95pqMuWB; z9ygLrD7n!Nh5;kaXfom!y{JJ(BX=N=3E6S<$Xzc z8rT@Rb(!uWkLF$ir2r^HOFNu@XHjW;5SG;_K#eHwNXQ^j*9paWGm@2mzr z7|lpUHB1^8S?*Rh+ExmWdu8hvl3`IhoP&PJWLK-^FAC^Wg1&rp^+pI5O+$AP_b5SZ zVeRE8aK5m)K^|yk4t%4jeA_ye9nLG}?Qeq5`4K3j_`ZsQY5Mh2_V33GlXW&j@ ze-4o*XM>#b{2Tt)C%2Y**U&M&*)Ixr0=$J<(#UL5;oi+_8445M=yh(F6IHgMv?RX< zsYA8kHtzF`LP)vda-y=;o48+Ww!_^`xv*3LV=_VWkPZAQBZi_BT3)75`HbK?VCAt# zulY5GvZzUS@<7RY&1@>YZ&>_GzXrnJ-U{yFM*nAh<`07I*{m=ye2~`f)maaWBg0Eg zm{Mt}FNRdOOaU{;PHI!(s7&~Qs=SlqN=bxtDjJZmBVQ_n!!h2Vfw~8oYSk2B-LyX( zr+062*MbKnqWl$7bCGq`N98mXDA>?68>(`qmN-Q$<^Y^c2-sLvA5(t>I@KRvrOFd(QCs!+AF>nAqM9!pY0A2@ zk>@(ok?8nL-E|$$!_L9P|;Q z|6pP=9gs4ngV>>#eysxO0(RJ;mdq)-<*3f3uyWbnr(MxkOb-i(>#Z?^U8IsE3Od6J z)vCb8U@i((^Ltc~k`Bd*@^>zo5>3d8zFSb6l5_F<*>C640PD@8$?Mr8Ie=AOfevV% zC`@yItu)*X87&gHsRrwNg~NUFAd5PIG=y?!25cGZ{Ed3>7&RlZORambvMV{nF((Qg z?6rbf>E>104KS9NlPWW3Wo9sXl(q29;2DH=H5pHRYk-eic){a=%91BRFztmkER)z2 z@IJG?Qk-^PLI0RXq|CO7(&biP=t5&8#|ur23SvgOuTGC;TP}L}s~t;&kNy@@A7w2l zU=(nbjL~JnOwfazz0eWFbg=T+lMvHF+<_w2WZ+9Ou#IROP$O2k1r`cjjI?U*>WFlh zopkJ*I41d_R%qXw=~=Nl^&8h)Vv&?~BchqT8Qq3UNNAW)G*^#>`3o+`3<)phZ_BI= zr%Jf=ua~DV@U)SbZ^&gVJm_k%C@e&P8NtnDg;Ehe9ph*0>e;~^$7-0fEZ9hYDbpz` zs>9Tyy*)fr{&Ot{f?>*IbQC4(Eauh?FMbAC~?!i(k@hbw&Go|n#`)j*bslp8{z=J29LpnfbY;r_2p@{>sVUDSBc(OW0>p zn{7`+oCl})v~_0vkXS-tPKFG|azSO+5q)nM(-0{70@|5-m9kNtyCD;R+j{W!Xk`-7 zt?8Q3KInmI<1h(klkeH=Gct}O#HA$dCqL3-BXM}PSc}fg;=xH@w3=0G1;!1s;%%~f z&(m2tqa75jRC%69M$Omv#rq(q%;iPcQk^)grvq2JHRcbz-uQA4>oBV92DCBb(bHm1 z!7>WeU~*zd zHJQ+oU#m`ZqqS#Y4Xp#Zdt^-{6haEoSui~o5{gWlMhLe=In?P*>HOzx9;dPN0geYs z{ex!RjTOCDCzB>jKQuA~caZP10}Hm?w(U%iFfi04pVgU>@x}BeO}s>NUQaV|ZgeFG}5c?Pz~xZsLgb+XU>a4NE&j zWZ8YR7{^|$`M@cSs-e*ht&KCU4mJ=6QyV=t5a+@d1(gbW9}uK*R@&L z=bPU3rgm5OBT7+KU)4KJM7TVLeUI!tA?}S8l#3j9piJ5QKLW<0+t>3l_Gl%2!b5OqB5tX6+>a_IsTgiD? zTqV?J`xkJTvY_BI9~|@HGNURItMOpe7JU(}umtaSC2@QgVHaVrDN$*$`iVf&$TU-^ z{^w67#Z&PFV{rO(dCLk~Fr$c~DZ>Ht%Ubj)l{y7= zQ>u*E703J%KD)x@OV9snV6Wq^@zR$Ne5B_;$%*y9b#A=b>c-G~hA3WaA=~0YUG@dM zNnsGvv`*~$gKC^hTuEeK>$^vPA02$j5Ksz8oCm=m4wii9@UcV*rpo<9&+sKJ5-55j zg)k1FT5>hOI^)`-uU>yO%>p|R5sO=jT=ac?5ehwtruc7=)VdFj0RMli@>w|lsk<04 zc)0#wuY4Zv|0M}aHX?_h0Z3R_|0O{D-}wTWnhH*9oG2YnXG<`&L3|0 z+?fS9x|5-mV4{!uLpRS*E&RMYVNo6cl0 zv?+Cj9-t=D%ox_nlDXCwVdu4f4#$Oa@Z|jbIp99wID8p?qbVb~w=nyRKe<%d7w74* z5#MB_GInIeLT22LIoN$5%2rt?r#|uP*XeWu>(>bpgWQ zKZ~7wL)~xrUTZO5QwntqOqCa3rA~*xGsaTmB!F6QaF0h<+v75-ovL(k?P9GgKrsPB z9`{2sh6Y}y`n6RmOT)RBuSn@S9L#4oS9ND=^{qRYv4t)nTT>oOlqDTAVi&<8erDu5 z{QyGjnoR89T;jJpe1dtI!nsmwYoXUlLQ6qcXf7f>#k$oEhresS94F0~CoIudO@oDI zdw?|<=jYh|PEN(Rh$jr92~Vqgsr}ETHrQxO-LD%X`nr1lFPNS6!b-wIB4#py{`BYr zoEHM}83RGD9FeQ<1<B1(D5{RHf6{}%EMap29vNCi97{z=awC9Eo=VJXLc zfu$vv@Ocg9{$4%bkz(7MUwRYNA?&^eQ z%Z@v&3qCXp$+h(iWa_Q)+dBQJy+Gon{&327*q9MOU2rAW(-P6mPpJTf*2473kOa64 zLQ6Wff;0C<8o0x$lO8&%$n4B@Dk*E-)ZP3$Tqr8#i8yIg^Tn2)M`I%X)Z`sq+~0$p zrUjFk@f{&h8RSWK^Ii(Ls;a6oOCxi|lC!5mVb}OjIY!DMt@a5oD0HKpgXYqcwef)j zWY^P=&7rTJcnTr0XM+~q8kFkb2m$aTy&YP=tAe_JT$Cy$#HuAk#Ht|}n3~lwzzB}{ z%Ut1Iks0Tzz)SX_aUk}Om5NppHaamoLHJLPmu^pQLNj!dnnJ7aj)fXtN=~-R0xrm zG_ofmt#j_@ug$V9{(+iX;-(eqv2Cj}G$}AsmX9?ym%E}~o#|=9n8CoGCNbSeR601E zM3P?4tj&s1GIWQW!e3DXt|vbN4MOV~^T!dzR^AT7{ITUMWmRq#EvWTTbxWg|*z+S+ zh8~M{F`3*&eXXDkP#U_P9so5?HbdphpPH6+Sp5bPCW;gRh+12Dpo3Zv&&B#AA=!yV#J@E_2ceDMMq}l#jAec)gn2 zxAwARl<(oeG0#Xoq^xXTI`Ia6+e;&W`Y8|ozm~J5L?P(Vc>d+t z{3mmT^`TF~-|A0T>eo>`L-h@Vx=OJ$C9I(-zEQ&QhC0+xSd!-Y zzA662SnzDVsi{$Msi~N8{-P7TBY5`)d}RMn3D7eGW;6E26r2JMb9`@(4$a$virL)= zqHSRf0*~(-l#m=0k(`R#Jvu&qXF#^>hfRXyT*C}X!whEH(?}vE4#!fR*%lC#+A^n; z`Q-yv9Q6}~fuCRZ9tZ{(w-H9d8Wh&?1)ClrFul{5!LdYCg2dPH%~=1UhUDmKNk|}M z0?-r6%IL|b2jfuB4XLEXkR2KvSfPu32}F<>Nzl8A$-y!FICHurO~ms-ic@vCKZpLp zak@A{^7?|Aoo80QqhWVKd9skk9vI4Tr=YUUhnnSX@ym2Oeg7e;eWU z@x5seKqZ5R@9ytihBbs>t*e%Jr+!PvHGL(1cl|=bvIEgO%M0ezN);PS%4VwepB@~;a30~4|hlpmLy8x*0OU>pPs>$@w+(pt#V*P$}lkN1V4 zE@Lwrg&vTsulhIF?_ahn2TX`cUkxPezF!jsFg~h`Fv1@((+?>;DN$QKHSa*uTQ=#} zm)fUP(wFAnudQf`%!-Pyd)2Ry>#sfNRV}TyuK{<}%DTBVEE?Y}*Pchk%Y23Z-7`4-q$ZE z_2uh%vvF+s^y0WAaeD3c-ChP($E13MSZDCnwNDrtI)`s}jk1dr$(MR;jW^AA z{Zoy_H*5y${2mL;9e)zQH-vK)e&3Vi;Q^5+15!Q%nnC1^zetEc68g77BM`eO?vOoA z=-#86x4cTfa+)$u0rD&^s%zr=q`7DN`=Ne$sxN;A5US}e5_;c}d;8%VjsE%G1A|W? zgvGDtFT;RL!cWXEN#-|fQ)uSYFT|CtR(7{0HsJTpr&0R~!zTdQ0xG}ww~L!yX%-%512+cO-+E87wYS1~ zQu%y8X|JhJsHiosyTCRlH(m^`ZLyMpo~BRTFTZm88M}YepKN>uevxyUSU`s~Q9n%` zZ7YO*4FH{207)$VFwQR@ESqs`OKtpRN6l}d+oRP2bj%Vp6{(_q+dNm-V=p@&ZQ^OA z2w&iqbOVz>7>Lao>WCZ z^h)lAU7}L?5P^|4105Wd|Jz_H{^|Y01cv0}GJTB=17YryGKJ3HqDegK`H#pU#~{2i z6FwrIEF?zMdyc_th=QVH{dk7S3=0|M{?cw;EKM!vFHu9c^~ek;qLLW2N-;y)0O8hb zFMKKw;CEx$uhxKu;F}aO-}vxmq)oQaT=7x%Py7|(Fe9qJL02DaxN%k)SoyFURnajQ zQq-rm_4>bNn%f!T+VVJw?ID=Cez19SXJ785jQXLg+*XGbqR^Ydhi41QM;9M@$`vDU zODGImZ%s* zTYu%5qw0A@lhRcpef^|K2e3`YQXlXc;6!3g!cH*e8C!Y^S5W;^enl|cfc(3pDJRU= zb{6#V?W99c_^q%?dz@6bd|u17{_?=-neQC3B&;Y?%q?doe}r=TU z(0|67Dzh$x5Z6cZ{iaFSGnkimFO=}JhTO6I6oGG5?(5dNrKtOnbV#i_@8?-96 zwK-Y{Onnexx@0bE{};o|NU*exE}*HEK9Xh|La;c}(Q80G&m4WQMcIEA^E=5J6Y%ji zyfR9Zbsl)vuW2|ga2}%bG;CD6^89JKz^I)W6nHODle;`0&on9?$}pIg7=2fqQ9OrW zMZJ3WiI@54bFj~iYYzsSps((6CSa}Xv}poKsUBuanYDTJ!~5X68)UQN3BVsy$jn%D zZycB8@8Nv?W^r^MA`ed)uCLM)O(EXwaY>T;`_G z#^`m_BdM+{&XYB)jp06+)(-L15CxVL&3i*PF?!|nt@8O4Ue#7eEf%KCopT^g;dXiXfGSGdumXnTXJ*FPB8JM-7U-t@= zcO<-jHV{{=^d1mUKbhUw0M`(8Y`Npx#cRy2%ukma-KqUKJ0H(T3Org?KWMI@>`xdy z3R9KfI~`T<;5xsQ)>U5nKfP}9pV)xx`i9AuLwo}h=&rSu0*Z!$YWhYhV2Ro=cGxFn zbH&zpt4fF0C<5a^DI)51mfXH!B|J|yN&7ad+1-f+aEBMz{y`|=OVWS=y^Vi%tKu6? zTA!}8rtcAm7*Cpf0m#{5804EyL&fr_j=q!n=Wd6kHT!^gpO#1_m=sF=-koa`#1*W2|5|mw5RKV-hm4ZB` zc?D05+eSinP9vFV&~}U`&TLkyH|y-bv=dq*xG0!S=%p{aLIqA*5o4OY>nz+qKUCn+K@eDcJ)hOVTP&|1Ukt9v zN$tGr$pE;d_~M}LgT-f~os*edx#Hmc$gI#7bwuuiH?C!ldIUQhWA0+LlsVNO&5ioG z%o4a>X354xt~4?K0^}ZBbkdoML3Hf!$Zp01)X6_OUx0GAs`n!D(|Pl?rLHT@Vt7Ho zSOLl2ld)Uxp4m9SY*QSs)x2AMuK3ZWM6{VLQ7{UY3ueX^(&$ITqpeL2g%qkljTB85 zG-%^0v8WI`ELGKMUV*M()+B|SB3W5s8E`O>8$7z;?2QOs z_Lfby>y;%UO_+h$V4fWT3lvXGJbJlXb&<^YTy~vKRlw-Qyz(3#PswC|B3I?8<`|9?x`GW z0RPQ{qvqSPZKeW}uj__KiO6PYdeIu{4MC!D>14>zCmNAc#PMa)A=jXFj{jzKSmE@057VUrivcQfHFVSsGuC|`@{%t6$wLterH_>f$WNhHp zyeH=I*VL%ru5+X#VZ3MG6ao_b;@wPr(Zply=Sj1+PT-vo08F@u2FGCsu&0afH*myD zz<9@gt=JMrWltYfTaOq`Pk`$c7UwEcN3`mUK=$glh1OIQaQ`4K8=SvXaK3a)dr)|7 zhCvVS+k7MUO4!O$o0CzCVbaXsM*=jyXoZL$O)fb6XfJ)s+S-!YH7bups#~X^ea;$< zwj+9ZP;KB?#mk6a!}fM{=dL)^`ofYfhh}g^MrN)r_p2Cxjgo>V6|XQIKP&x0-eTpc zp{p7CN zVy7-vFXqXQ>v8c%tb7||jBz>B-{+1zhrX%rRgD&n2*q;yYvPLXASr;y4%i+kLsziXc+WlQvg1R4< zzxWZSRY10WaXp;u6-2q%co{8+d z)b%4u*v?Fw6y?~MW42XAs4f%SXw0LM4%N{1IP+axCKHZtqcwhz34Rb@v6Y|$qJam` zf_=EW)90AJ2?@cf67>M82v_HyC-Be#!N0hJ@;tM@O%9xi^MYx`Z6CYX9HPj9VHE`v z0dJ&2fvY&_WAHU#-x@yiCy~jjNX+YqM~;p^Lk#C{f2hwHk?G=KuNnx0G1^ zf7j3SxAQm6+mv#fgbN2*R`XrhYd!yjI=g?e!r|+@Ku=;=QafNOmgq({lDx32|Lj0d zV&NV2Xv%S-MLOT`Upy^D;vTP$DIAyeC==&{Blo)*L$5# zRgPXHlGFI7#rU>*0fUB?tV42aAAnJ~v_=&(_unhQf#Gwt5BV1!cVO zxzSd`ubQ&|br;?=!t(mIt21B|VP`|J#mj{gG>V$PG-*f?@1-kC<10T_=qn$4+WQh_ zwj!$t`wO@g$#hg}$c@B(Ao)X*%P-O3*k7)0eCCTqFDiO6}PRtip zh%aoRmaX1>{kz??KP5Y=n)0&YE)Gz8VK(*Sj!S@!!DCx?vM2t}_M)7wkxTlNxbN{! z{0`apjcI=(cxuBr9A?JM%=0EqVS8dYW1?sF&nbdyt4M^}4U93)D1gSYz8Kp8$ANe5)y%E%Ip zFYE)=*3TQAj^XW`K0ZrPXrT0e1C@^lu;q5(D49gd(vdsQU*eghdZIV$e@y9h9fUJP zs4_)e+i*IeIk zaY5!QKkJ4U^bY|6IkMay3|+{!?8gm~G$#ejJ$|s3$*-u}X^nl)qpD9!3s&CN8xhRK zD|JWdK11M}Tdu0|03%|y-!$l}OSLa0swljoGphO5gF(UP}&z&*o7Od4dJ`mNTc{P_k1&}u%XZK)46SF|8 z1=7$8Za2Ga2PXaeNkwltuK7FSPxLx^41!r&!^NL8mD#7Wk1T->-MuA~Q^8xE@}<$f zN{rn|@R&^J3OU@)^5+BoiPek&^o@CTV%i@GN{SN}RGFpx-y^2#O;6YYg*WX0TD`Pc zCBhc|8i0`gDmHfEnsDLZXC3W+0GxnhsK*tE1R5+a9?x!>8(RuLtd9@(qO_( zMBomkC!j6;Fo*RvCoBkK`sVuPa8@VE2J%5u+R{!pJZ z=E8%Uc(Xd8sY6aTOmk8xH0_gP0zo1RG<`0nZC`qgJWA)E8)&iIsqY6)R|ukMFBBbGb^qAeg6n6hF++F7$6 zvS~p}U76VCh8to%Xlu6WHOIsMLVC#B4@rSo${~>#Qh>IF>7!2S6SUw2<>VIF)P{EEmkE@IF{$SjR$HL>n7e=#HDG0=0AhBwG_EGIp{SP6E4 z&6YcE9BzwZevgk~b7zpSqgPxuV4Zqeg|#0wI^+G+cO=gVd_PjBd%-H04GQ$F)x)zY zK4ZFs`gh8zqRd}71+9N(Tf1nHKQ0c5b@Uny2{ehDMkV}Fzl4juuvIA5RKjLkS7pMp z@7^WPUKlkU$Tdo0ED+;Y^Oe)|Ruz|3Y?yj+g0*ylHVUxoz%}ljU_!ltbIp5iorxPa z5v82U5fr2W2pa;*EL(F_FgN(i`0BE1c84_?&V6AsAV_SK@PDR${0_j&Td6x;{P)H{ ztWHoHv?r5?tmVBpRoS<%GAlF)2TLf$Y5%SrAo?>wle~|IdLCVEwLB>+tt_6$XEo0ZT%7Fv)}g&h`iIjo zVyhMjcUm*eQ<;ZGd3}mW?=G_X1$?A1_xiq1V`EqSGS?6GOpf7K&3VtK-`;s*)hbSu zqo*#kBewVh9*0sb!x>CjZ@r)v6)2kL>)`Va&`1>D*0d_BLItI$Nu-~ZYuy!i{6sT8 zHEe8pWj<$jNl5+fUT-I9tF2t2cnn9KYxrLPSwN=0@#G7zS+?BG-KU8guix3OAH!`9n;4w)5V+y+$gcFtbgJyqU_I zP~v}IrsG^BKQjpYK2U^}@{O7;jVLQ& zztHmo9ktsXNAbVWi~tS{ggU4(h4f%GB5PZHX7erDv=PvJPIf4i#K>gbu^isVxyjGC z3mRGg5PrXB^N>0juzm)PS1lcScea6`$NPlyE4X5RZzG6Odv+RsNS+@0bwOqM$w_~` ze_zrk`ddnOL#;==qEx_(Mxy6;3@se4^*e)+?Lu0-{-ao=eclp`wFEeIq#va)b-rG! z3Y3G(`+*Ucs;yOX%KN>gLj?Dht6}b)eGaiz;zu-jQDVz4W0)VQN|-u+G;bPXZ((z? z*k!uSRVcB7(I7U#f?3YT#u>~VbS!@XoIw=+qCri8&g*`1mYIB=3n;Y#xsuwO^GG@|-m;dadVvB(BC5Lid-XL1W z!TjcE_V>#kh4vZzMN-VTE8M(lSKlawW~xipG0YyswE2}M{JRgwape-$2jPDYuBxW* z5VIn1XKz8t3zC=oDHL1Q$}=L9LYb6o*g;s@8xD_ga$$x+)=MFCvx?H|o1uofze&6v6G9&+R ziB!O?WNyP-?);8`nT9k5+%wR!QO9Sj%_y zeL=3?hSKR}hSt^m-2Hl0|5zzmOQC^O$E2T~|1B^<~5P1(6Yo zjOARy*qHb`3oVTcdV-S z1nj5imbu`d&n$gC~-R2b;5r*J@_5$c)3lvv_DZ> z#Kv2bTV1X_qXQSvF7ERH$+HtXvEa<53~_Cc{h{@>!D_e}F=VP|NVQC?d4{o3f&C7N zl42N5994__F~?wE7meUF31TOEkp^0h`Q7dbcqeDECm`r_kfy9EZE_>neSZI1xew}t z#H24b)w-zy>nDHPEDzMPaPgjR z#Afa}BiNV(65gB0Q(s>AX&(~Dwxz=Fq8k`YeVNL7w*$r(2_$wSEpPYqg1A8XK!dk6@4;qR`Oj0>DBrQ4p&n$e%NXpH)L8_ zC`X*rsZq)GVM*h;uDLm7!*PlyIt6uCR&>F-(>laSZwuVh9wectX**MTO%vY9* z9hQAwY59NJjyUAx8Z9{=h>0VkSMz=;b6i1M5{}4I^lL}xbkhR``l?(FUn;dB+mgYC zGM!~!@nq69Ux;V8W(P_4$PLJ*-hHzQ&afLW)Q2OBgs5ssR!#XdUDJh1M3auxhp4F0 zCa3q@-(DhO>Qvk{-O0mf$!K{$nuq(3y$hy~u7!VJt>Romh-$s*^yrsh$3M7@=^fA8 z*<&;p-X`Gg*352F3Y=3uH;ZuRdSh4}g1Ga(+-Afx9A*4XBkWUXXyf|xvUBg&+qu*yV=$^pFylFTe4 zJKcL#f(yYk-`DM}Y&*o$&ASod5J6r-8vPp}@z+z!wfqZ(JZPMqzIU&AXbj((2eWP9 zxTSEBYz6~BNqxF)9tV4J!Qm2pi7OXoyLNv7bY!klB>gsJ77b0n4e@n_zZWgMsxyng z80?1!C%R4Oyg}fK=-gKXR`=c*9-sJF)(|`$t>tQ~dMG6tmve*jm$fZGYWBO~h}L`? zTi)&aOK+odA`O?Y@lxyH6M!XSR#8evvCmS3FqW(rG7=}1ZcOLtO0jYo0+FkoMnQl7 z605Fw$K7n_9dlle2vDUQJMME?p6&9?|yDxM@W>GcWQw z-$YCsQ$r?bA%8b^Bd_9fT0&qy6qJ8g3ahmu4oeowdaD-s0BQ7bEhv)FjqB9b{ARo` zL1S6q*g#fn04=l81+Esoc73v-Vs_0^1^YY`3KMLvE3XeFr8H++w@p5o#kL5ZIzt;w zq|xXrLpCoJokxmWXvh8xGOYZ5dbTrjV(>z(ZYt`lH$oz%qcG|E<%91;oX^-#KqPK>m z+D|qrM}fLqaGCbgMg6e?YIo`Vs&?~#?CZqR+!pn)X07$zdDfh>ZC!enYY|7A;j%|FW=i1Rha zOk&7;Z^q{}|JGjqGTr6LP7@~{;kj}FrSLnz^E{q@;3e_ya-~7{%E?Gn``GDZ(Q(2& zn2h0Q+q2arIsZa6uOVJV{Gb-qUW&a9g-hJ58hB8e9N-)H33r&Vvi`3*?U7*|JFqgivX-IrPnr@iKAj_TJGR0| zrjFAqWcGwE{L;CO2yLm6p*rq9B@K0`Nydmcljx{aNnDppMEwQv*;yWiWehNGLRB*` zqU?$Xh;k-s3)Yx6Xa*ym4j5M7^0@szsI7(RDZM+M#fyJW+ayQFL#N9&FCEdC#U1<{ z?Z!B|J zj-BB0Lg`8*<)^VgaOzL!(|AP+!v2=fmvNnypm9PKV=kDdyO1sSdJVol`sOz3@EA_* zEz%^;`F(%wEf&%e`%Nms9xYzzwr@OrDK(45pLPz}bG_JRP`&Br*pJL)2l8zqOFVID zRXG^N3-;BG@A9&Y-1%Xr)(L1?qp4r|&Ehu5;ti=bDHqwNG4re2N1HQ>V!aQ7?dweD zZZ(+PV{cy?Xe^CsA*Jc3+p-m-eRy(ba!%>s?JAytvt&4=pSyruG@d(mR34 zA%)Fdt!CH#6nme9`Vne(h4yi!N=WWzq0x@>x^Dg97;eYfgcE};+WxRmJ-xSJ2L%EwAl5jLYxL~M5hs;60Kz9W?7x_+G zX5=Q3ZX4*T7gkOn?>eL8WQ=f(@mD`I22Z2MPuh2PT+z+k&;$r1X!H?Pp5$svUdpKXOEiR( zM2Ia3KH9WDTk5KnUPaa%rUpN{M(_7D35UCV+257f-d9Gow_Fr~6t|Kz?q=)J1ip5_d#zr3mC zOk(medZdKi(&2E^V9h9)cl9@kymi~n@wb=s(s3ibgVelVdy{`Ax-XtX zTb`_`QGG*C;mWN{5;u~D%E4{v($A)kNb0|#bY;k(l79GNi=AW{QD#_bdoKzfSTK`( z>JRrA(WsdXi1HjUDuAWO7F6`YNNIOR)CkznCh!{|$xO0CSIjA(sH81VJyBYFmhu+K zeW`hcr}ORaf;)Gp^SAYd$fSSOKTrNmkB$Xi^3e;%Mio4~HrV`n7K~?eeYn^8N}56j z52}=)9AoL8Nt(3KDr3!Du`Z_;CyK%v3k+K?(YaS)UW-N-FR?eF!HN5pn(MVYS0C36 zNz+5OGY|-iWb%0MW2sL(^SsZ<5tYX3biWWnuat1OaAh8pb;Q^yb~1l+Ue72&eGjJfuSmc zw*B@ATWf^q2~fD!SCNfuFilx^yVdIzivpY5l!Ci zaOLcf(U}q!b?4|f5c!k1?3hrit4ht&|nY;a8x zH>;N2o_6=RBz7gf%e`f*Z9iXO$@v(RSCo$ZJl-afa{EbMu|9v)-hcQ^ui0Nctjhe# zxS?voU?`h-Cb=OCay5+Ok_cRR%Yp<1OJ68u*C(RK?zQN7*1NVMB>&zH9alg?eMGpE z@l>Vv*JMn$@=n{wQce3POm&dKJ?!m!wx3(X^+?8L|1tuw1kt+&7&}Dp_mJ*$hD`gK znFdA2$5*8l?ofZi+t{L9XH02BBVgJ8<`ydAEVheNCdXEhih2x)(H?fI;1JGVNWr3! zQh)Ttg@$kRL){mljs3UO!Bm)-S2-;?{FbHc_Q^W?O3)KEU6I5 zW%Ug&l%)FCFJ-eAE0Jwquc~JIe0pA+j3Hr}{Uh8h7!^l5G_C-u#nPg}Ey zd%#efCfOa$M9*^i*e^c|89bTF^<~y8WaWWJy$W8( zu4}bk+W1R?+fa_O+Qx@lPb!vjchSluo`T_hZN`nKc-xy?kKmsWXUXspY8nC@O#JREa*MI?XM#5i7WtBP`T(c=S@4 z8^j5JdTgX_oCR<=pYadRW1g$4ZhGIu(i{duZbim^iN!RW6{WpQSDo?wee!bV_*s>^ zTe%LRyGz+6qyM~sXBKDIS!tKtuW2Wvs46#OZ9&ft-MoB*oko~y21Pra4_;^&V5>B~xPxx>zCUFDiKOju>^j*U^u^ku%1 zI%bs)U@W<3r}593&l1b;Gp*Ij0GiB;MNog@EQJi(8)1P;7U|o_JGE*IhHFzbepiJd z1g=as_KWzklk$;v$B^ODg_)%Qsq<|)rY2o}uc-(E{H-U8T6K+~nBd0dfsX4t#Qbl; zGb{p4z2S3UQFs1DI=QIDL4=!U&UNH$^v>Lu>{%aLXRD&mDQ>&3`ZmH8wvh2h0(O7b zTo5aO7f&kLxl~zx=eR{;N5LK}3KMd9p7YToDf8^Ntkh`W;;EsR8m!>!A z0NiSaXCiroUn^|9)>TF6@!GS_dM@ApL`xfRi|6f$CWPOB>67tB&EeW?`AOP+kWPp+ z(;YoyQ9nzy2q_Y7nGABBmuVRCODg^TI2|Hdluce91Y3-n;fBw?Gd>c6FuJnj9#(^C zrQ*znI5X>T;5NdTCF2~rfC{TMz`k&+_c=|V>y#;_d(ol$1^0Ft~_M#@~?m{S4W;lrR<5C zOSMRIl{0mX$8N|>DGP0Aj1_V}Yuk@pb+I}N+X=gfOq@VC894vmg`;P$4+8o_K`{Bf zTI+ht4YaLF?U?Vf*zJE>j0FI*_}H^%u%<3MT6?khGQ{cMBipLWON(F!+k4f!JWD92 zf-}XF$L0}KD{ZxlDi#A=d2k~We2!r4v>23&Pv^Thhj`Icfq`$`= z5R;cc;{ZxBRzVO@%kSVCDKn8$xV=?phWj8G<3J6WmUi_`HniVB@5e4zBuIukJUF%? znDphQ^>;6mr+_C&qcJ&z@j+qZtFCqxkdRS;7-GyrBNLHu`zi9oQe`}$+%Q_r_&goL zsP!E@hJNAC=z@QnFexsAhit?j*CQ*-r~#+N&6J{h#NzH{Wy|3h<99=N51m~tC{;^z zT<}~%Kk6E>xom{sF1tjl*A6M=NR~t{^{GTS(GQ=w=*C8<>ov}8;-OK_g4(tD>?ih| zF_@M@?*U^^IHrdPa?{)W+4t4fFxfwXJoNeCQDRzy#P)xPgyDw}p?o$VeFL9L)9~#qLAO&^dj^9QR+EVGrissJW*Wmowi*gD9`3^Q|i=>ES6leV5Tnl0c81 zH5#odvQCZP7xf5$$ay~*F749l8c$?RisRg`v<$H6_rvidDAn@@{QCG2ri`2h+Nywl zxfHjmbK$#WZX10HNcxe5Hz9x^&I}aCHt>gPD{Cp`Nn=;%VHytiR6tBr8eb;&(Jj*f5@Omb@|N4Kt<6xs zPr!iIr^_Ma*>Uz_8&)&paQFlj^U{_mLGo6;F;l04pY$qn9cYAXbP~8wKi==M3GG+S z4?KTyXWVpGwNh%T`CZ14d_4Dremp?=luxr;uk%QAigP&Vkz-_&fEZ#K@B49=O1~

|jSk~J0M_?TvE3ESp!$tn{!2U~g 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 delta 49411 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 P2;Ag=@CNE~LSXz4z?Hli diff --git a/docs/white-paper/main.tex b/docs/white-paper/main.tex index eb93ab1..fdeec6a 100644 --- a/docs/white-paper/main.tex +++ b/docs/white-paper/main.tex @@ -32,7 +32,7 @@ % Title Information \title{EulerSwap White Paper} -\author{Euler Labs} % Optionally add an author here +\author{Euler Labs} \date{February 2025} \begin{document} @@ -40,16 +40,16 @@ \maketitle \begin{abstract} - EulerSwap is an Automated Market Maker (AMM) that uses unique features of Euler lending vaults to dramatically magnify capital efficiency using leverage. Unlike traditional AMMs that require fragmented liquidity pools, EulerSwap enables a single, cross-collateralized vault to provide liquidity across multiple asset pairs simultaneously, maximizing capital efficiency and scaling liquidity across DeFi. Using the Ethereum Vault Connector (EVC), EulerSwap allows market makers to borrow the out token of a swap using the in token as collateral, unlocking deep liquidity without requiring large static deposits. This liquidity-sharing model allows EulerSwap to achieve up to 40x the liquidity depth of traditional AMMs, efficiently repurposing idle assets for optimal capital utilization. At the core of EulerSwap is a highly customizable AMM curve that governs swap exchange rates, ensuring deep, just-in-time liquidity while dynamically incentivizing market balance. By combining on-demand borrowing, shared liquidity, and flexible AMM mechanics, EulerSwap eliminates inefficiencies in existing liquidity provisioning, offering superior depth, reduced costs, and greater control for liquidity providers. + EulerSwap is an Automated Market Maker (AMM) that uses unique features of Euler lending vaults to dramatically magnify capital efficiency using leverage. Unlike traditional AMMs that require fragmented liquidity pools, EulerSwap enables a single, cross-collateralized vault to provide liquidity across multiple asset pairs simultaneously, maximising capital efficiency and scaling liquidity across DeFi. Using the Ethereum Vault Connector (EVC), EulerSwap allows market makers to borrow the out token of a swap using the in token as collateral, unlocking deep liquidity without requiring large static deposits. This liquidity-sharing model allows EulerSwap to achieve up to 40x the liquidity depth of traditional AMMs, efficiently repurposing idle assets for optimal capital utilisation. At the core of EulerSwap is a highly customisable AMM curve that governs swap exchange rates, ensuring deep, just-in-time liquidity while dynamically incentivising market balance. By combining on-demand borrowing, shared liquidity, and flexible AMM mechanics, EulerSwap eliminates inefficiencies in existing liquidity provisioning, offering superior depth, reduced costs, and greater control for liquidity providers. \end{abstract} \section{Introduction} EulerSwap enhances trade execution by increasing the size of swaps that can be serviced compared to traditional AMMs. This is made possible by combining a novel AMM curve with the advanced \href{https://docs.euler.finance/developers/evc/keyConcepts?_highlight=operator#batch-operations}{check deferrals} and \href{https://docs.euler.finance/developers/evc/keyConcepts?_highlight=operator#operators}{operator} features of the Ethereum Vault Connector (EVC). Market makers supply an initial amount of liquidity to a `swap account' which can then be amplified through borrowing. Specifically, when a user swaps an `in token,' EulerSwap borrows the corresponding `out token,' using the `in token' as collateral. Later, when a swap occurs in the reverse direction, the incoming `in token' repays the outstanding loan, and any excess collateral is returned as the `out token,' effectively closing the position. This leveraged approach significantly increases the available liquidity provided by EulerSwap and multiplies swap fees. It is somewhat analogous to MEV bots that provide just-in-time single-tick liquidity to Uniswap v3 in order to capture fees on large trades. -Beyond individual swap accounts, EulerSwap takes capital efficiency further by taking advantage of Euler's modular design to allow multiple swap accounts to be built on top of the same lending vaults. This means that the same idle liquidity inside a single vault can provide depth for swaps across multiple asset pairs simultaneously. Much like Curve’s 3pool, but generalized to any number of asset pairings, a USDC vault could provide deep liquidity for 10+ correlated assets without requiring separate liquidity pools for each. +Beyond individual swap accounts, EulerSwap takes capital efficiency further by taking advantage of Euler's modular design to allow multiple swap accounts to be built on top of the same lending vaults. This means that the same idle liquidity inside a single vault can provide depth for swaps across multiple asset pairs simultaneously. Much like Curve’s 3pool, but generalised to any number of asset pairings, a USDC vault could provide deep liquidity for 10+ correlated assets without requiring separate liquidity pools for each. -EulerSwap’s exchange rates are governed by a highly customisable AMM curve (illustrated in Figure \ref{fig:fig1}) which incentivises swappers to maintain market maker positions in balance over time. The EulerSwap AMM curve is a novel construction blending constant-sum and constant-product models, allowing swap account creators to tailor their AMM parameters. Like \href{https://berkeley-defi.github.io/assets/material/StableSwap.pdf}{Stableswap}, it supports concentrated liquidity for correlated assets, as well as \href{https://app.uniswap.org/whitepaper.pdf}{Uniswap v2}-style distributed liquidity for uncorrelated pairs. However, unlike those more traditional AMMs, EulerSwap allows asymmetric liquidity deposits, where different amounts of liquidity can be added to each side of the pool, and single-sided liquidity concentration, enabling deeper concentration of liquidity on one side of the pool relative to the other. This enables it to simulate the behaviour of atypical AMM protocols, like the MakerDAO \href{https://mips.makerdao.com/mips/details/MIP29}{Peg Stability Module} (PSM). +As illustrated in Figure \ref{fig:fig1}, EulerSwap’s exchange rates are governed by a highly customisable AMM curve which incentivises swappers to maintain market maker positions in balance over time. The EulerSwap AMM curve is a novel construction blending constant-sum and constant-product models, allowing swap account creators to tailor their AMM parameters. Like \href{https://berkeley-defi.github.io/assets/material/StableSwap.pdf}{Stableswap}, it supports concentrated liquidity for correlated assets, as well as \href{https://app.uniswap.org/whitepaper.pdf}{Uniswap v2}-style distributed liquidity for uncorrelated pairs. However, unlike those more traditional AMMs, EulerSwap allows asymmetric liquidity deposits, where different amounts of liquidity can be added to each side of the pool, and single-sided liquidity concentration, enabling deeper concentration of liquidity on one side of the pool relative to the other. This enables it to simulate the behaviour of atypical AMM protocols, like the MakerDAO \href{https://mips.makerdao.com/mips/details/MIP29}{Peg Stability Module} (PSM). For end-users, EulerSwap functions like a typical Uniswap-style interface. However, behind the scenes, it incorporates advanced mechanisms such as borrowing and repaying, custom pricing curves, and dynamic liquidity provisioning. The main target audience for liquidity providers in EulerSwap AMMs are professional market makers, token issuers, and other DAOs, whilst the main target audience for swappers are leverage traders on Euler, aggregators, intent solvers, and MEV bots. @@ -140,18 +140,18 @@ \section{Curve} }{2c_y}. \end{equation} - The curve coefficients in these equations, \( c_x, c_y \in [0, 1] \), represent liquidity concentration parameters, determining how steeply the curve slopes to the left and right of the equilibrium point $(x_0, y_0)$. When \( c_x, c_y \) are close to 1, the curve behaves more like a constant-sum AMM, while for values close to 0, it behaves more like a constant-product AMM. A full derivation is given in the Appendix \ref{sec:curve-derivation}. + The $c_x, c_y$ parameters here are liquidity concentration parameters that control how liquidity is distributed along the curve, with values closer to 1 concentrating liquidity around equilibrium and values closer to 0 distributing it across a wider price range. A full derivation is given in the Appendix \ref{sec:appendix}. \begin{figure}[h] % 'h' places it here, 't' for top, 'b' for bottom, 'p' for separate page \centering % Centers the image \includegraphics[width=0.5\textwidth]{curve.png} % Adjust width as needed - \caption{\textbf{EulerSwap AMM curve.} The EulerSwap curve (red line) consists of two sides with separate reserve values $x_0, y_0$ and concentration parameters $c_x, c_y$, allowing liquidity to be distributed asymmetrically. This means liquidity can be more or less dense or concentrated on one side of the AMM relative to the other. The exchange rate at equilibrium is determined by the pricing parameters $p_x, p_y$ and is fully flexible. You can interact with the curve \href{https://www.desmos.com/calculator/gzwmvbs1dk}{here} on Desmos to compare its behavior with traditional constant-sum and constant-product curves (black lines).} + \caption{\textbf{EulerSwap AMM curve.} The EulerSwap curve (red line) consists of two sides with separate reserve values $x_0, y_0$ and liquidity concentration parameters $c_x, c_y$, allowing liquidity to be distributed asymmetrically. This means liquidity can be more or less dense or concentrated on one side of the AMM relative to the other. The exchange rate at equilibrium is determined by the pricing parameters $p_x, p_y$ and is fully flexible. You can interact with the curve \href{https://www.desmos.com/calculator/gzwmvbs1dk}{here} on Desmos to compare its behaviour with traditional constant-sum and constant-product curves (black lines).} \label{fig:fig1} % Useful for referencing the figure in text \end{figure} \section{Conclusion} -EulerSwap enhances Automated Market Making by leveraging just-in-time borrowing to expand liquidity depth dynamically. By integrating Euler’s lending vaults, it enables market makers to amplify positions efficiently while offering a customizable AMM curve that supports concentrated, distributed, and asymmetric liquidity structures. These features make EulerSwap adaptable to a wide range of trading strategies. However, this efficiency is not without some trade-offs. Swap accounts incur interest costs on borrowed assets, which can erode profitability if not offset by swap fees, interest on collateral, or token incentives. Additionally, EulerSwap inherits Euler’s risk parameters, making it most effective for correlated asset pairs with high loan-to-value (LTV) ratios, while volatile assets pose higher liquidation risks if positions become imbalanced. Despite these trade-offs, EulerSwap represents a breakthrough in AMM design by repurposing idle liquidity in lending protocols, reducing capital inefficiencies, and optimizing swap execution. By catering to professional market makers, DAOs, and algorithmic traders, it positions itself as a powerful tool for on-chain liquidity optimization. +EulerSwap enhances Automated Market Making by leveraging just-in-time borrowing to expand liquidity depth dynamically. By integrating Euler’s lending vaults, it enables market makers to amplify positions efficiently while offering a customisable AMM curve that supports concentrated, distributed, and asymmetric liquidity structures. These features make EulerSwap adaptable to a wide range of trading strategies. However, this efficiency is not without some trade-offs. Swap accounts incur interest costs on borrowed assets, which can erode profitability if not offset by swap fees, interest on collateral, or token incentives. Additionally, EulerSwap inherits Euler’s risk parameters, making it most effective for correlated asset pairs with high loan-to-value (LTV) ratios, while volatile assets pose higher liquidation risks if positions become imbalanced. Despite these trade-offs, EulerSwap represents a breakthrough in AMM design by repurposing idle liquidity in lending protocols, reducing capital inefficiencies, and optimising swap execution. By catering to professional market makers, DAOs, and algorithmic traders, it positions itself as a powerful tool for on-chain liquidity optimisation. Future research could explore optimal strategies for setting liquidity concentration parameters dynamically based on market conditions. EulerSwap's design opens new possibilities for AMM efficiency, setting a foundation for further DeFi innovation. \section*{Acknowledgments} @@ -159,11 +159,22 @@ \section*{Acknowledgments} \newpage \section{Appendix} +\label{sec:appendix} \subsection{Curve derivation} \label{sec:curve-derivation} -We start with an AMM containing reserves (initial liquidity) of two assets, \( x_0 \) and \( y_0 \), and define two standard AMM curve models. +We begin with an Automated Market Maker (AMM) holding initial liquidity reserves of two assets, $X$ and $Y$, denoted as $x_0$ and $y_0$, respectively. In the absence of trading, the AMM remains at equilibrium at the point $(x_0, y_0)$. + +Our goal is to derive a curve for a trading function that supports swaps between the two assets with the following properties: + +\begin{itemize} + \item Passes through the equilibrium point $(x_0, y_0)$. + \item Maintains an exchange rate, given by the slope of the AMM curve, of $-p_x / p_y$ at $(x_0, y_0)$. + \item Allows liquidity concentration to be adjusted via parameters $c_x$ and $c_y$, which control the liquidity available for swaps to the left and right of the equilibrium point. +\end{itemize} + +To develop such a function, we first introduce two fundamental AMM curve models. \subsubsection{Constant-sum and constant-product AMM curves} @@ -174,17 +185,13 @@ \subsubsection{Constant-sum and constant-product AMM curves} xy &= x_0 y_0. \end{align} -These curves intersect at the point \( (x_0, y_0) \), where their slope is: +The constant-sum curve is simply a line, whilst the constant-product curve is a hyperbola. They can be thought of as two extremes when it comes to the distribution of liquidity. The constant-sum curve concentrates liquidity at a single exchange rate, whilst the constant-product curve distributes liquidity across a wide range of different exchange rates. By default, these curves intersect at the point $(x_0, y_0)$, where their slope is: \[ \frac{dy}{dx} \Big|_{(x_0, y_0)} = -1. \] -To introduce arbitrary pricing, we extend these curves by adding pricing parameters \( p_x \) and \( p_y \). - -\subsubsection{Generalising to arbitrary pricing} - -We define new AMM equations incorporating custom pricing: +Since real-world markets often operate at variable exchange rates at equilibrium, we introduce custom pricing parameters $p_x$ and $p_y$ to allow flexibility in defining the slope: \begin{align} p_x x + p_y y &= p_x x_0 + p_y y_0, \\ @@ -192,52 +199,55 @@ \subsubsection{Generalising to arbitrary pricing} x^{p_y y_0} y^{p_x x_0} &= x_0^{p_y y_0} y_0^{p_x x_0}. \end{align} -Taking the derivatives of these equations with respect to \( x \), we obtain: +The constant-sum curve is now a line with a slope parameterised by the ratio of the pricing parameters, whilst the constant-product curve is now a weighted hyperbola. Taking the derivatives of these equations with respect to $x$, we obtain: \begin{align} \frac{dy}{dx} &= -\frac{p_x}{p_y}, \\ \frac{dy}{dx} &= -\frac{p_x}{p_y} \frac{x_0 y}{y_0 x}. \end{align} -These results confirm that at equilibrium \( (x_0, y_0) \), the slope is: +These results confirm that at equilibrium $(x_0, y_0)$, the slope of both functions is: \[ \frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}. \] -However, equation \eqref{eq:exponential-form} involves an exponential form, which makes it difficult to evaluate numerically. To resolve this, we introduce the concept of virtual reserves. +Whilst these curves sufficiently generalise the constant-sum and constant-product curves to an arbitrary price at equilibrium, in practice equation \eqref{eq:exponential-form} has limited practical application as a trading function because it involves an exponential form that is computationally intensive and impractical for on-chain calculations. To resolve this, we introduce the concept of virtual reserves, which simplify price calculations while preserving trading behaviour. + \subsubsection{Introducing virtual reserves for simplicity} -Note that in the interval $0 < x < x_0$ trading should not depend on the initial amount of $y_0$ liquidity. Swaps from should only increase liquidity beyond $y_0$ and deplete the $x_0$ liquidity. This suggests that we can split the domain of the AMM curves into two, and replace the real reserve $y_0$ in the interval $0 < x < x_0$ with an idealised virtual reserve $y_v$. Using the equilibrium condition: +Note that in the interval $0 < x < x_0$ swaps should only increase liquidity beyond $y_0$ and deplete $x_0$ liquidity. That is, our trading function in this interval need not depend on the initial amount of $y_0$ liquidity. This suggests that we can split the domain of the AMM curves into two, and replace the real reserve $y_0$ in the interval $0 < x < x_0$ with an idealised virtual reserve $y_v$. The virtual reserve is chosen such that the value of the reserves, as weighted by their price parameters, are equal at the equilibrium point $(x_0, y_0)$. That is, we have \[ -p_x x_0 = p_y y_0, +p_x x_0 = p_y y_v, \] -we derive: +such that: \[ y_v = x_0 \frac{p_x}{p_y}. \] -Substituting into our pricing equations and simplifying, we obtain two modified AMM equations: +Substituting this into our pricing equations for $y_0$ and simplifying, we obtain two modified AMM equations: \begin{align} y &= \frac{p_x}{p_y} (2x_0 - x), \\ y &= \frac{p_x}{p_y} \frac{x_0^2}{x}. \end{align} -Since these curves no longer pass through \( (x_0, y_0) \), we correct them by adding back the difference \( y_0 - p_x / p_y x_0 \), leading to: +Since these curves no longer pass through \( (x_0, y_0) \), we correct them by adding back the difference \( y_0 - p_x / p_y x_0 \). This leads to: \begin{align} y &= y_0 + \frac{p_x}{p_y} (x_0 - x), \\ y &= y_0 + \frac{p_x}{p_y} (x_0 - x) \left( \frac{x_0}{x} \right). \end{align} -\subsubsection{Unifying into a single curve} +Note that simply shifting the curve up or down like this does not impact the slope or shapes of the curves and therefore has no impact on trading behaviour. + +\subsubsection{Unifying into a single curve in the region $0 < x < x_0$} -To create a single unified curve, we introduce a liquidity concentration parameter \( c_x \), which determines the curve’s behavior: +To create a single unified curve, we introduce a liquidity concentration parameter \( c_x \in [0, 1] \), which determines the curve’s behaviour: \begin{itemize} \item When \( c_x = 1 \), the AMM functions as a constant-sum model. @@ -256,7 +266,7 @@ \subsubsection{Unifying into a single curve} \subsubsection{Extending the curve to the \( x > x_0 \) region} -For \( x > x_0 \), we construct a reflected curve that also passes through \( (x_0, y_0) \) and maintains the required derivative: +It is important to remember that equation \eqref{eq:EulerSwap-1} only works as a trading function in the interval $0 < x < x_0$. For \( x > x_0 \), we construct a reflected curve that also passes through \( (x_0, y_0) \) and maintains the required derivative: \begin{equation} \label{eq:EulerSwap-3-inverse} @@ -313,7 +323,7 @@ \subsubsection{Extending the invariant to EulerSwap} For EulerSwap, we apply a similar principle. Given any reserve state $(x, y)$, we check whether it satisfies an equivalent invariant condition. -From equation \eqref{eq:EulerSwap-1}, for values where \( x \leq x_0 \), the AMM curve constraint requires: +From equation \eqref{eq:EulerSwap-1}, for values where \( 0 < x < x_0 \), the AMM curve constraint requires: \begin{equation} \label{eq:invariant-x1} @@ -340,174 +350,4 @@ \section{Disclaimer} associated with Euler Labs. The opinions reflected herein are subject to change without being updated. -\end{document} - - - - - - -\subsection{Curve derivation} - -We begin with initial liquidity in two assets $x_0$ and $y_0$. Basic constant-sum and constant-product AMM curves are given by - -\begin{align} - x + y - &= - x_0 + y_0, \; \text{and}, \\ - xy - &= - x_0 y_0, -\end{align} - -respectively. These curves pass through the point $(x_0, y_0)$, where they both have a slope given by $\frac{dy}{dx} \Big|_{(x_0, y_0)} = -1$. Suppose we want to find curves that allow for an arbitrary price at the point $(x_0, y_0)$. We can generalise the AMM curves above by defining pricing parameters $p_x$ and $p_y$, such that - -\begin{align} - \label{eq:cs-2} - p_x x + p_y y - &= - p_x x_0 + p_y y_0, \; \text{and}, \\ - \label{eq:cp-2} - x^{p_y y_0} y^{p_x x_0} - &= - x_0^{p_y y_0} y_0^{p_x x_0}. -\end{align} - -Implicit differentiation with respect to $x$ shows that their derivatives are given by - -\begin{align} - \frac{dy}{dx} - &= - -\frac{p_x}{p_y}, \; \text{and}, \\ - \frac{dy}{dx} - &= - -\frac{p_x}{p_y} \frac{x_0 y}{y_0 x}. -\end{align} - -Thus the new curves pass through the point $(x_0, y_0)$, where they both have a slope given by $\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}$. Unfortunately, \eqref{eq:cp-2} is difficult to evaluate numerically due to its exponent form. We can simplify the system to resolve this issue in the following way. - -Note that in the interval $0 < x < x_0$ the trading function of the AMM does not depend on the initial amount of $y_0$ liquidity, and in the interval $0 < y < y_0$ the trading function of the AMM does not depend on the initial amount of $x_0$ liquidity. This suggests that we can split the domain of the AMM curves into two, and replace the real reserve $y_0$ in the interval $0 < x < x_0$ with an idealised virtual reserve $y_v$, and vice versa. - -To find the idealised virtual reserves $y_v$, note that the new curves will still need to meet at the equilibrium point $(x_0, y_0)$ if we are to maintain a continuous trading function. In equilibrium, we know from equation \eqref{eq:cs-2} that $p_x x_0 = p_y y_0$. Thus our choices for virtual reserves must be $p_x x_0 = p_y y_v \implies y_v = x_0 (p_x /p_y)$. Substituting this back into equations \eqref{eq:cs-2} and \eqref{eq:cp-2} for $x_0$, simplifying, and rearranging to solve for $y$, we obtain - -\begin{align} - \label{eq:cs-3} - y - &= - \frac{p_x}{p_y} (2x_0 - x), \; \text{and}, \\ - \label{eq:cp-3} - y - &= - \frac{p_x}{p_y} \frac{x_0^2}{x}. -\end{align} - -These curves no longer pass through the equilibrium point $(x_0, y_0)$, so we add back in the difference $y_0 - p_x / p_y x_0$, giving - -\begin{align} - \label{eq:cs-4} - y - &= - y_0 + \frac{p_x}{p_y} (x_0 - x), \; \text{and}, \\ - \label{eq:cp-4} - y - &= - y_0 + \frac{p_x}{p_y} (x_0 - x) \left( \frac{x_0}{x} \right). -\end{align} - -We now combine these equations into a single curve parameterised by a liquidity concentration parameter $c_x$. When liquidity is maximally concentrated, we want our new curve to be equivalent to the constant-sum equation \eqref{eq:cs-4}, and when liquidity is maximally distributed, we want our new curve to be equivalent to the constant-product equation \eqref{eq:cp-4}. Thus we have - -\begin{equation} - \label{eq:ce-x} - y - = - y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-x\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{x}\right)\right). -\end{equation} - -This is equivalent to what is called $f_1(x)$ given by equation \eqref{eq:fx1-main} -in the main text. - -It is important to remember that this curve only provides a suitable trading function in the interval $0 < x < x_0$ where our assumption about virtual $y$ reserves holds true. We now consider what a suitable curve might be for the region $x > x_0$. Note that this region is equivalent to the interval $0 < y < y_0$ on the $y$-axis. The curve we seek is something like a reflection of equation \eqref{eq:ce-x}, except that it should also pass through the point $(x_0, y_0)$ and have derivative given by $\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}$. First taking the reflection, we have - -\begin{equation} - \label{eq:ce-x-reflection} - x - = - y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-y\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{y}\right)\right). -\end{equation} - -To force the reflection through the equilibrium point $(x_0, y_0)$ we can simply switch $x_0$ and $y_0$, and to force it to have have derivative given by $\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}$ at that point, we can simply switch $p_x$ and $p_y$. Finally, we might as well allow this new curve to have its own liquidity concentration parameter, $c_y$. Making these substitutions, we have - -\begin{equation} - \label{eq:ce-y-1} - x - = - x_{0}+\frac{p_{y}}{p_{x}}\left(y_{0}-y\right)\left(c_{y}+\left(1-c_{y}\right)\left(\frac{y_{0}}{y}\right)\right). -\end{equation} - -This equation allows us to calculate $x$ in terms of $y$, but we would ideally like the opposite. We therefore solve for $y$ to invert the equation. This gives rise to a quadratic equation of the form - -\begin{equation} - \label{eq:ce-y-2} - y - = - c_{y}y^{2}+\left(\frac{p_{x}}{p_{y}}\left(x-x_{0}\right)-y_{0}\left(2c_{y}-1\right)\right)y-\left(1-c_{y}\right)y_{0}^{2}. -\end{equation} - -Since we are only interested in the positive real root of this equation, we have - -\begin{equation} - \label{eq:ce-y-3} - y - = - \frac{ - \sqrt{ - \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right)^2 - + 4c_y (1 - c_y) y_0^2 - } - - \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right) - }{2c_y}. -\end{equation} - -This is equivalent to what is called $f_2(x)$ given by equation \eqref{eq:fx2-main} -in the main text. - -\subsection{Invariant derivation} - -On traditional AMM protocols, a curve is usually defined as an implicit function of $y$. For example, the classic Uniswap curve is given by a implicit equation of the form - -\begin{equation} - xy = x_0 y_0 -\end{equation} - -for some initial liquidity values $x_0$ and $y_0$. This gives rise to a natural invariant, where any swap input / output amount is allowed, providing the following invariant condition holds: - -\begin{equation} - xy \geq x_0 y_0. -\end{equation} - -It is easy to see that this kind of invariant can rearranged and replaced with an invariant of the form - -\begin{equation} - y \geq \frac{x_0 y_0}{x}. -\end{equation} - -This is essentially a test that valid states in the AMM are those for which the $y$-value is on or above the AMM curve. Similarly, on EulerSwap, for any point $(x, y)$, we can simply confirm from equation \eqref{eq:ce-x} that when $x \leq x_0$ we also have - -\begin{equation} - \label{eq:invariant-x1} - y - \geq - y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-x\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{x}\right)\right) -\end{equation} - -When $x > x_0$ we could also define an invariant test for $y$ from equation \eqref{eq:ce-y-3}. However, it is simpler and cheaper computationally to use the inverse equation \eqref{eq:ce-y-1} and check that when $x > x_0$ we also have - -\begin{equation} - \label{eq:invariant-x2} - x - \geq - x_{0}+\frac{p_{y}}{p_{x}}\left(y_{0}-y\right)\left(c_{y}+\left(1-c_{y}\right)\left(\frac{y_{0}}{y}\right)\right). -\end{equation} - - - EulerSwap is an Automated Market Maker (AMM) that uses unique features of Euler lending vaults to \textbf{mag}nify capital efficiency using \textbf{lev}erage. By borrowing assets as needed, EulerSwap AMMs can extend the range of their reserves and earn fees on trades several times larger than their actual liquidity. Under optimal conditions, EulerSwap can achieve up to 40x the liquidity depth of traditional AMMs. Using the Ethereum Vault Connector (EVC), EulerSwap enables market makers to efficiently borrow the `out token' of a swap using the `in token' as collateral. This significantly improves liquidity for swappers. A novel and highly customisable AMM curve governs swap exchange rates, ensuring deep just-in-time liquidity in the short term while incentivising balance over longer periods. All of this is built on Euler lending vaults, where a single cross-collateralised vault can provide liquidity across multiple asset pairs, dramatically scaling liquidity and capital efficiency across DeFi. \ No newline at end of file +\end{document} \ No newline at end of file From e4d307f46c7001a4e241245927b736bf90d71584 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sat, 15 Feb 2025 13:47:33 +0000 Subject: [PATCH 108/312] improve abstract flow --- .DS_Store | Bin 0 -> 6148 bytes docs/.DS_Store | Bin 6148 -> 6148 bytes docs/white-paper/EulerSwap_White_Paper.pdf | Bin 341616 -> 340346 bytes docs/white-paper/main.tex | 14 +++++++++----- 4 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ca2b7874ee44cef1857d5487e8c8184223131c55 GIT binary patch literal 6148 zcmeH~F$w}f3`G;&La^D=avBfd4F=H@>;(h`8(BfodXDZ-CJ2t!BJu;tpJXO1`-+{7 zi0JxuSc&u^GJ~7S(n4d3ypw~RWiQwJa2ZeM@rat$Cvn!+@Lrnz*rt#G36KB@kN^q% z5COZlVY7KvMiL+a5_l4@??Zx{=Fn2rKOG1@0zf;I-LUpq0-CG<&7q|#Dlm=dL8DcD z46(YmLsOi~p`~hV7meXV4M3`}dgXhH(h?7~0-B+w9;*1Wg-e+&OK|2Hj6Nq_|Y zjDU8VVY9|d#ohY$dRE^>)z$?L_2URHKLJSWDqg_du%B!J&7q|#Dlq;CI0gn1_$q-1 D?w=C8 literal 0 HcmV?d00001 diff --git a/docs/.DS_Store b/docs/.DS_Store index c6ed3bc813d5c2fa54f333e65c71a4bece1e61c7..08a0f61b1e0fb0385acab587ef755650807e9ac3 100644 GIT binary patch delta 278 zcmZoMXfc=|#>B)qu~2NHo+2aD!~pA!7aABR8;Gz>>=&<3DlaZb%E?b+U|`shRFIQd zTw-8wjgg6&g_Vt+gPnt$BQ`iAzdX1kv81%vDX}OT#0$yK&q;!@6O+O+Q_JH8M4a>U zN)j{kQj5SEGE-84N@Bt@^HTE5o$^cbQi{QPgCPW z)s{vEK(?`2Z7nBfYER%etAJgP#NF&y5Ga cGf(Ch(G>y7f^;-MXt3tZAtD=?CpNGE08A=KPXGV_ delta 72 zcmZoMXfc=|#>CJzu~2NHo+2aT!~knX#>qTPQkz+rnOQe0Fvl@%X6NAN04mum$o!po aGQWr}CnEy`!vP>>m~6u%y*Wl?2{Qm^ix2St diff --git a/docs/white-paper/EulerSwap_White_Paper.pdf b/docs/white-paper/EulerSwap_White_Paper.pdf index f70beb9bedbc95f47658cf8abfba21bc550c1145..2a5f5f9ffb81f1f6fd94484d2a18bd2371513484 100644 GIT binary patch delta 59058 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 LfixW+Sls^uraLel delta 60268 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 Date: Sat, 15 Feb 2025 14:18:38 +0000 Subject: [PATCH 109/312] replace virtual with artificial in wp to avoid conflicts --- docs/white-paper/EulerSwap_White_Paper.pdf | Bin 340346 -> 340642 bytes docs/white-paper/main.tex | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/white-paper/EulerSwap_White_Paper.pdf b/docs/white-paper/EulerSwap_White_Paper.pdf index 2a5f5f9ffb81f1f6fd94484d2a18bd2371513484..31fd22ad7e09dfe4d8628cff2525ef9e01d0252c 100644 GIT binary patch delta 26234 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 E0NH`7umAu6 delta 25943 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 XKs8eS_n^%N0nuuYj+% Date: Sun, 16 Feb 2025 04:26:46 +0000 Subject: [PATCH 110/312] add security.md --- SECURITY.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..737d2b1 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security policy + +## Reporting a vulnerability + +If you discover a security vulnerability, please report it responsibly. Do not publicly disclose the issue until we have addressed it. + +- **Email:** security@euler.xyz From 7bcb6a141eb6927d6641655a1501bb693064e533 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 16 Feb 2025 04:30:57 +0000 Subject: [PATCH 111/312] add docs to security.md --- SECURITY.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 737d2b1..18e743c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,6 +2,7 @@ ## Reporting a vulnerability -If you discover a security vulnerability, please report it responsibly. Do not publicly disclose the issue until we have addressed it. +If you discover a security vulnerability, please report it responsibly. Do not publicly disclose the issue until your report has been addressed. Resources for reporting: -- **Email:** security@euler.xyz +- **Email:** security@euler.xyz +- **Further reading:** https://docs.euler.finance/security/overview From 1135971f49760ef2198821124589a8c3e99a5c84 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 16 Feb 2025 04:44:34 +0000 Subject: [PATCH 112/312] sync readme content with white paper --- docs/white-paper/EulerSwap_White_Paper.pdf | Bin 340642 -> 357912 bytes docs/white-paper/main.tex | 24 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/docs/white-paper/EulerSwap_White_Paper.pdf b/docs/white-paper/EulerSwap_White_Paper.pdf index 31fd22ad7e09dfe4d8628cff2525ef9e01d0252c..6d328a0dfd5d7767f96cebf5b015fb8d1767bc47 100644 GIT binary patch delta 90451 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%0A?=r}SL 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

tb$W3nM{%3K;Gbx2b2QhLpHZ<*zXB3v+> zggSx6tAP>8fnETUe>9F$%Bl(wLF@?a24y}_3PXml7R62>2gOsfsEcqHioT$k`$DrA z6jM+M-)I?mT9C`D;%!H`kNH*qRU5*|#7ns=fx4-f>+U(rzPTp}GnoCi;Vk^!>TdtL zq4UV#C<|vr2+B`>tTv{lC3q4(`LxKa8Z zN8E8KwkB&;c)*ODpM8_oO6aaR+iSDR_3v;`AgLzi&g_=E?0L96W%J?lu#hVom|4O!=MvzAovKnqQn|*>>D!~T6fCkQ^UT0PA$}Wy zo&Ixs-gB{qs|$km^X9eft)P3>?`W6m06Y}ENof2IG?aT#eh~po4nJEs+}=1Xwh<+m z$^s`iMQ}T)Zzr~G%Bozi5uq}x$$Xio^2O$6CZ6q{cNE%BE%{Uf&Xs!hVN#xXW=>cX zi?*WyobPZ-*|GwgT7Cvil_8HE=Ys`Tj%p@ox1lx>r-a?vG313-cB2GjJJ3vGE)|4q z)O#ZXyC)d;ro4d4So&HTB${CZ$*EgJpzD9KelbfUwrsjfZhpWCIE z?l$jf;sR@CmV70Ff5sfmODiOKOs-)mZH+?uIH*w_y=4Avd&;Vpj3OAxs9kz$w1-Xm|Z8RcnBjawfXtf2JxzFmhM43ko(LW3onfQr2!S9 zn?d461g@AJ8DrtbQr~sV+pUgWOa3;7@sHLQcuq0!U#`85pJ=F0536$NOmP;Yr6Q7H zh(tToZ~O#2dcvebyq&ZTd*hHIqd!dshP<|q^`7X@kCK2&#Kb)?ne{qki<{$(<;NVV z3tk26mI8@-wU z#NwCA5HAj}yevUi%Py`gt7D8h6c>x{$gQ6mS@H$h@m}m>dthq0P+^>U$GZuuUMteZ zV{6GD_~hCJr-P%T`C~l9>UHPMcY3Q1VL?GbJV(}lth=Ox%+@Xr!yh-c4l*o@SN++Z z{Tu)nwphIdooE_-6SGlF4^At^fLCKniiGj4i!~$h88vx*(Qic|(kk^UE`&9{v39Tm zPgMl)o+i}jlHd6%>v=CyTQhI^;2wJ)@Ovp|leUmgP`0nT+OYs)EY~6BQqwdtza*5)mU^L3!MP3Tfqz|V%X?U+ZoO;r_mq`ZsjHdx#o2| zY*W*!jS@kM92JS9>{PvG%XInx)AhqOjgZZ-Ifd#U+9`>;Pcr62Wvi8FRvSq@7K1OD zkmK45Bdt>^vr}CCY`z}(U>R_K#GdnmEG6*W%!DxUYCanGEQhL}E>aBorNlW{FO&f& zllV%afM0O#iAH&rb6Hk!;oM~G@^A6vH;+VOe%TV)SwgjyQEqgl25P^3&SeLpIfNvu z&kWFbB#bmdirq5gByplxmbI8ia`WfHBYw_b3+L%uTsGpCnUdl?YKeu&EXfBMPxxBA zTJu93t#@nV(yzRBwAmd+KHO_XOTGZfyksmMd6VB^hz<+-hogqk1s|wM=dm6xDeY5f zHzohg3|J0J^J|@5E8Lkd#!9N%aa>4M-6@Zx(9sb^sLVZ<`pHDk&O=ap7v6C^vgs5= z&Ij(CXB65Gu37vbOcF?!W;GPf(Ecz-KRiE~C*PQI;X20plZp3n+T<#?ui*l=U8;YU zxL{7XdBYc9b`SgchpsO;f6Rc5#7e2-+sT$WJULMm~T&Ri!dqLJNdJpHU?IGUl-9|9bV@Id`+d%Vuph zGWLA|Pfsyjh9>&Y9;%@DV(C6Hy3)&6quD))AUV~6?ID)Bwr_AoSBQ3f!ZrvalZvS$ zrB~n)IduaO#mNxaIX2D)#==nk$B1I^8q;8`Ix4YI_1BV5WuthA+x>rlvPTz<<&6x8 z^1dPYdlG}QIPai&K_8#UE{3{8B>j3$0m(l19)4ZZiRsS$;MGtq&!K`M&{Q$n`68 z&8FRVn#A*@Hl#&7NV%Ui)sPN(&j!|lihqcI@cc--c3e|LpnD3(N<9+`$Qmc`|0xQC zxgsbtbHYeii<$o(-eZPN7C^zp`Z;Is2DWUpIf$%TiyP#pM7C>|aV#{Eh3FicshRi8 zbSAx3NAE>I5){w?Tn@KZusxdMOZmiEg)-+IPsFuv{ZTQqOTIK4klbqcf~UQ4V{e+* zA_apuQDKldL&If|qzPU-d#8i6TWR*tG=&-+`At7AkwP#%d(9q4@s6qMx2OECX~|`6 znFHonk}w4v!5=g{qc4B1kkY&b5^edB7tgx{*)S-X3vNw=fbg#uHO3z^%%H@8!gZ^$ zg-4>k?44Xg7L80LpXse+q2$~5HaFS8L!ss?kMER?=DGoR_1D=yepwMzUz>bW-RTEQ z!<#7`{5?+`CVS9H94KzO506x6lrF29+ol$$`>6}oQ5nK)-bt%+IqYMxnD1BYxQsjO zNP|rX?+TwI0q_UVaPQ+`oZf?F26~D<`x}+|73btzKa8?u=SB+(Jxw=eIpBN8F(b&k5mO3^SVQ-dXeR4q z!i2|+&hRcC)}Mf@Syvo;<>jJNU-$q`c~6Wvq!j z=JM>`2Bc5TLbA!jcw2P0)5|88n+A_+sPrYGkruAakwxFj-Y^c7iY#({b#{7BEsSWd z@{{wS7Ic@J__Nc{N=HMtkzeJ(#A+_XU6v#M7Rk<++Ck$HZt50 zD)oAL{3nSaB%i@LU7L&D?59VU=L(vOa3N|aW5sAjfy zo}1lz3YvfJFDva76K|?(rFC)QmQdMBNlSR^=MvHwC%#cZ1b0rhOFR!|{dK3Qb#z$1 zp#XfbQ)~%WrB4%7>_u9Dw}3(`%?{^xG@n?(9Yc0uF#1w&33Tj>y-AD-GDoGjdy@Y8 z5viX+bX{Y=HsVfbf@H)yITDH;C+2uGYY=|4D6zNsP~#sfYJh2v_72r(+U>s+ol}+` z(1}|Q749F_!}_xj-7!dxxthQqDg0R?w*#WUc{jRW%Fjw7+ylx{5(Jp0z3Tdk{J6@v zJi25tBhWvOymaU6iH@EioU;%sW4_!co6*r&4ZH4vdg9p}VG~mH5Y%Vlc41-7FRs4D zeo;dCt3**c-4RJ`!_|YtfED8wm-zH{!J9~gj04bH zBymyjk5OnwRxXNvx-05^KH#w3JgT}2Ctl8&AO3ztgqI{9X!^@#GgO|8X=fmE9_}@i zZoYj|zP8z39mNXzOn7zVeY|!JvzHnBm@~Jy0DmSqsQlJHml=*A*@X&8#y-A_cGKzb z>YLNLLb+Bd<}aVR-)JNhBmKUvQ(`M zW8!6_HY+90aVG}MZ$!UQM$k>ClPTG6?}Z`M*t{trWZPu*)RBuA|1HUfBBa#R#B5^v znNB5}6;PlNx~XhvR-`w^Rj%NrTx`zwLldKn_IANT>_5pxrwp^T? zqT*S{0pAAk%nlK$wFt6)?h2h#Z1SNkA?q(5A_cSx(S?qd!85jSEXPffgr+0BaR{iM#m znopmrBbs;Znz1WpYLh)%94wnwR$D{3sxUt`8_u(w#KQ+y-SQP@w*~-MdfA0aYG>R% zAuoA@DijG-$n22hdq3UQHqmJ}sg)4viw4-!<6@j1ulW{1ie{foGG_9rTy~R%jrUBb z%FK{d$p)G-(>fTTRT3uLWtAKnNcczw7}&Em{^I)};@vlgB}e4;eG2DQr65DoS#!F!mvaa=&f~WQiNg~}wpXBmBj<87O3}Oy z7MioPT5e)R-=$nEAn(CAv2ik4D(!gKJKn^k&gLv%+iIxer8;!OFltn9;tY{12;wL| z+fB!>!&6dDCE)L4l&3cwQ~kEu-&ZyhmGDSJ=F?SG_y`AQ*$_aMxdOZ=K08xsAz|k5 zGBwAQyYBR_UsE+Sk?lS-qn%cVu~`cZJP2A8^Q-;pOIzd58|WO_vNyz2sd%lWrJ!7z zZ^|kG^ZU{!Z#5@7Y%EH6x;V`+t~RW(n~|^HRlHxKzZGV_Gzj>}ag8sv2YrRl*etw5 z`(tYvXC`4jRmTEAV^D2+m!|0&f+Uq=G^Bx|s}-dVIS$Cb_spHJf9}twp?)C~9+_4l zZK53>A+=EaTR=>^;pw*RAJEOA7n;<7xU4^so@to778ez;3$0c8qO7Vm{wc!VEW6m@ z_T>x5ks^Se9;0y1i9 z5=7$SsHmtgM!a8PV9gN0@pybg63fYjppPJ&U18I}eXx)em>MBJbZ{a0poJ!8M)&Pn z$^u%-Luy#jz%Z6HQz6cEgotb(OohzALJ4wc=wTI{p;kU^=pLKE0m7~94X_m4lu!H% z;!8chinC8g4i0vgYA3eF$J*K^uoSIj2=H(WN2JQEN@p-5uR6Wp!A1rY5MbnHM5|?l z8PlVeiVsN^m)T3aYe#XSZw6cM=HmC6n4OZy z`uEG6E8}1nrIpbouw`(0i^|kg%gOqw5}2C)Ex)xRF&PZ+pI-zz?8K1;T`}o}RgQxFE)b#lYSx#{F`DD*=YV3nAa~I{d#= zhw=km=zOfK-Q%NkSo#q4)wLm?goI=;X`fNTeQu36P)96)pKCO3_uc7b*XEt@smX!9 z-Rb@6Th%j5xRvBscxlIL+s@~Ss3-v+xWJvYESM*@D+SnX75Ofd_w}nA4!Kb|F!R)> zwz9DX-u>>@n8Wc-Y4iwS`@UrF=77KPCiz2}Tls;VY|2y)^-mfjyy$-by7yh$ADVD$*CM`^0IfLDxM8%&+LWM0Wvg?n zd)50>U(S4l7I;o?{kbYm`xTy6J|{IUvAlGDbM>Z4`+YHSS#udOkwCk`hhG)!E@%2J z8pT<&h$BZL1ks%QQwdx+`PNR_!AlvoPLFc1cM$ z2;{ur*MQ^9`+QSqIO#$U)!F5QsImGG2ML^ilG?^hK5;^rnBL&~m9aZ;a5RAXZxA0; zcI{VuCVqNDeyaG2q<%xX{n@g_nhQc%I1F0XPzF;C+*W**m*pWG}%P+O$+)lK2}j_n}7%bPv8o z-)$mxBkVXr@dW6m04a`d#^oTp!bKt68ta$6ZmWK-6or0ds)oCoisROg!S>$&<~tv5zsBqmQBCC1GK0p{m+V z10n7=3h<8q2Qfg-zY!Q+EuDdXtTU*Uu74g5e>i~J<@N^zP1XGm2+G6bkBtO*|3StA z3h(v1qaasrp!46c|MeI(b#n%d$@Q-n9q35@ga7*30t9*jP2uNf987sbt*b*@?<$4y zJ?OVb_$Mj0HNVi%`^-CkcYAmX^O>e1EqK-WM)>n!7s}G6IQ6yA0`arYVN)&4hkxb- z<(5a^C&M_E@$DA)xiPH1(cDAfnqERU0(v!}9p7gsUyUFe$R_Z18Hy|?H?Frz-_Y+o zdL%t-dW#o_!e+LWcPcn!5uS=C=%dx6^nwbeD6&n`r*TN3UFiv7Y0=I+k*BV2CeboS zUx{Vn-og7FMYHDl=&Z5C+)sNimw&3UxOCu>?O%y&-xVRE%nWL zHu2>VXCl!hFVUkg?6IU)SgAzXH*{CI56!nRZ)JT3gi_)6p>HKr6*XWOI+H45RTv&8?FO7Pu#BUI9}`+Lnibjh#M^wNA@}Kla&nNg?8#g5-A_kcI4jT7oWgg)ogE8xBoT1qt z+f)KGJ6se~B!wd(@^3e%yWvd8j@3lmN$eV8ku}x$A2x?O@}E5DihrfWD5&!0<$GoK z`9Ap0>(7bhb>mhB3SoV`ZU|(l{;qgO4ThM8vK&K^wzCLHX83)uLF4=dPXu38?d}_y z_ZnFD?8NXU$`5mnlXT;4m3*O`P2>kaR8p$FpFM*eaaz3LT= zYrgj-{CXYQ;N+`fg5l~1aAP}99G^2MJSDT0?fXmczeeD0SyfQXBxaDzj>F5bfMHkZ zW_(4x+RO`}A&D}7uN4eyx`!GG3%1EOO@%Q~9h-Eng093Wo_|deO3zb;N`<=iGA8_1 z2DyUa&3sR_sLTkMjB7C%Ww#F}^e2ugc(NdkvF@>s!|55RY5auCNXDWcZzX0eJV+(j z6JtHjRl~`BD_(;fl=((>N0Jc`#*O^z`O=A)nTmX2Q(pO6_U%q<8}8@QRt7E4R*^{iQ-1{qag78oIg<{t5DbU1-spaAyX5jz;$vf;CcNZ#9letRTR=wQ|ziGEHhEmvcxf zk(1j#?mv_^(kEcA>2}~8P63ApBk%h0U~y%KW+_=HED}vByg%H^4B@8GxjFdDm$LNW zc(1s{r+;L9nBt)Q+CrO;)Z2wrGXBclK2o?U*pnlhh-FHH^KC-EMa6N#MJMENGZ!=e8cvj$_- zfC#@()z!l>2~&KhcD94}J^Atd*lm9xMNe7#_V*eo5&hw0WkrUh_gx|P z0S^BFRs0t9&~vNwlcmB#?TpWsA{yZB7iLH~chhM*%r{nb`5lx4r1D1xc0EE3n$uxr zIDffic1tD{O!Hsf&^{P_J%s7WPFPJ~G{5dnxBX6`B+in}L!=>0qbefDxWiYBb;6Eb zESe#lvwE9u%UkaAvjc&eta(oBjlBePJSl7>*cY%+E+3UShj`S^9yM(0Ekn&S2ovF# z09juLc?3iBnaN~L)YTV)xbH|_Tk?Ca9Dji&Sycw#Z;f3uh+%~knGdrW)4?Rpi4*Ht zy@<$CHcgS`9S9QRtip4(6Ab@^1io7ME64$e^*Lp*!wOAH6G}B2bGUws5_#i5r2+~ z-G6zdoK=COru2I49+Gtr5BxzF@A$HS7vdaXnefn<;D&YnDKyIHovjZZ>@86FcIK0z zkU2I7E1uMDc@pfY7v ztUV14-ns17;qb|~NNDAX42l_RR)2J@TwEnHL?K7rVec(6`StkMgh(aU9%Lo%)Ur(; zzr?j^1jX1=+gg-&rZ1RGltnL-H0~8oCr$saRyt{n0QlyGl2Y2-B)4CMjh zT?}lFzqy#jq}sprj_ZVlDa+Z-<(VOn%kak4k3l^vc1DQE`&Jy{t{~PHDSt1?$xSXT zXZ1pvAUtP*ziw~K;RXId1};`YvF?IT7H<1cX*gFgMpziUgt zo=qFeuFS%2WyR@;j>4l1x_@jrs&gzR9*OTv0j@>4CkjA397_VRq3UIXUeXj2BLA%t z-glgidbu8+xM2PB!OBA1(!W&*%cY2W!VE;2l~jRlRSQ(@FKoy!~;K3mn}qI+4-|!{SnI=6VYmoJF`ll4II8YKxYMGC%aV z7Mlr?-4=3zjoB!Cn2MCG1kak}&FMIpO0W%*c%X(xn2S=ljK~M)U0csHdnxUDJO+<1 zLwQ=IZH?gT%g_G2*?)^3ie3!q(vi>2S0@>ZBr0z7USt28<=Xeb9tuq5gb|562c_>l z8{?=U0p!J>zLSo#vbNqTanEue=|sD5e*mX4+AJeNI&xmnyysC!%sU!znY`{#Y#y5BOKE zGGo4xS8Dur5&LbEJqYz6E) zm6VwyUFW>irvdHjUi4#aC!k+z)f@q0UgYhZ_6MbhEBFx!aCPx-N0%>AXOpra9n;8C zQB>7+0^mBzLVqL3((`Ms6ggY3NogIrg*2Q!lx9RlY$2vBW ztH{xZT{O;B&jxSm^?3?MbKf|XTU~12`No!T#r%al0Ds-tPWbi2Zj&NFQudSO(1io%*9wq8%n|dxSL;$M+U4N?**# z>BseMDn_PKDdqSa+o8}Jk!{fteVhDKYq|Cw7zTTi>ff1<^m}_1x`z<28&->Wm;d;X z8Fs}Y=zl)d3JVQ!aM^l2`=MJ4+&G7X3wJu#4nAq|1CE8qJP8au>>cN}1e~^zm#V)1 z`TI0AMCu!X{_pSBisk~ zt-EeC3nS%vR74C2RYZ(!+Ydc!46|mn(|M}dz3(eVM zmN+M&7+xLOF9mhMBDE<#ZMq68yrGvvvQLUk7JOs4f@NU%e$fIWzRo`bt1p%}+K8xf z?6^=?2eQE0j!?wa@{EXGu+nI5m^x58jbx%td7o1#rn3wb-VDA^PWbk7TW&$F zwsNA(30ge>_F=qac&E789;b=CAi=H3F>hv3)ps2PIZDjk{zSk*2vwG01lAInB!BsZ zAEBRZsm~|t$YF_^frHB1jCPI+?6RETn$N%pUz+a4xfSCGsid+sou?axOCVD}_b;L@;D+S`SbnYgkPd!~8f6^%zkkE#43^Fz}5_<^d> z%(not%gJU`%eO;QQsZONkPFkGw>D?g>gJM$FAHJb%x?nnE274|g!S6712`r4wR8(Y-+9a1R z*!J*JCRLE}?Jj(+ya0ZpF(2QO@J=;q=x-4Gwkd52CZsAwnZ)<{rZxTq3V-Ns55|Qa zlr9lWptq?}Rm|FZXqB**jYO;WJQsQk;!$8|!1lh>snqr3$S3g|w0OmrQ~nW0<2?g}pgGG!MSmMeqx6Q8)J?~` z2gEWiH?Jjf=ZmD}%g=7`=6i{D{ z8uQ*Xz*+k#675A1sDGfg(OA#Qk5jI7xF*3jscBoSaq{YtYv84*6WEFhcf}|8>060jA%_+uibu~L4Ad!8@r)o zD$HHoJahgdvMXcM6vE3|^w7o`{2JTGD&{i#aKlG20Y69RcYizP#TML_?P2-9{qo$jDNMrw>&Hc6Y3R1bT=S8Bk`U3Lvp;Jq^Xl$Tdh&pfVGjh7yGn(6*#@v2UXB#jN?7;5_H*&iZg23~IDm@~` zoLLIrtNq$%u)u+T!kFPT{%B-;mW`G_fE1xyF%p4dG=I@HB%YDe<$>4v=E#@`A2Hi| z$Ld1PI20Sr&-zE@?x4_PPQ=B`wuQLUzqG^-}=0*uocuP^1h7x z`~xjgpmCS$nAnkCZk%!;=MnN$)<^(gR9i^VWt8;oWVwCNrC6}p{bx&`f!@$C7d~&Om$Qn=K>qggl@LFyx zE**n-plyX1u()|;6VzhS@A|}6DD`#tTk7n^SA)(mCpn-)b=nv8<4b?U+r0SrF;0Oa zn!eo26e;^p84%5dWx|}K`#xe}DtwGAuFvwl{eM^YF5CHmk2c)WT37MrIYnvXkQ=X~ z&yVlW=kvA1j|!4d1{e<3Njk>5Noi#kRXN{wENBx|z!L1eIkjFyBBY#{7v7UWd{?p) z-rm##i?)Eqf1RX|y-m*HUag9!rj7cMY!RniF8P&hq~K&%FcoZ+>gMRS`#wMd+e|}J zZhwaE-7c03W~t;$?wSE(W06yBH`L$_xMfr?a_RlO4pFIhs92G!5F+a>5bbMf=AQhV zkbpG}pQfeJmV9ft!0YU{!B_uv;M%cscAwgS@W38|InFc0 zmz?-SB|qLb5u}r?vNw}tBXMe34R0lGAAj_A@t$uDrV=0t@gNa+Q{Xy$4^#kRdOg8N zQf^Zmugbm8V_&G!m01T&csQ^>Fw+hf~oMv{`=?B`T-$SxHw4vzkW{*kmqR=T&7E+;G6-DS(DJXYJUw=qV z4PT8BcL=KS91G1!oMP`PyduD;YIQC%Rq>V5v{!TICI}&bw>s=8UyC47-!Rp)GdcuPJ;OJWN-Msu|9?ZMq!6uz!T4)hT$W`puluK zH?1_2AJ$}@9;we9ChRGz`hs`g`JmgDM4CC|(0uOuYo*n~A2i~h!nu%xpVafx9z1Bu z&n(a*equUJ@vNCyljSv4EMbOQ!Z`IKR1 z*aqlac)R$%5BAIHk(;hnMUTki2{bRBwrefu5@tP(ojFrQVCmt9Dhc#=ue zTdKh#DkHeSGCf+r34FRo_J#iG+Gfo>-j^!8>--XdS>7>T{(?Is9!dyi^;TK{oG`5JWAFXb zk3&`el3&Si^B61WV}G3*pjBDTQ8`aRMYka0R?#8%SyPdtn8B=Xy$nx?WOp`sPuKvj z9D7$5p?pcSftSK{X=vts3*(y|)pw1Wok+Tk=-B|ILqwYqDG@T0NhWw=f603Uao(6> zqJb1Bh2#l|R?Lp8Ei;F^d&^$2IWKV01}Ro$`;Be*p};M=p?|lQx>%x=NO1MNnP66# zzArDA!2Md+)sT;5Z1j<2<>Bi@72zAjGa}K3CuuS*2|=QJgh^541X9+g-_B0zriaFF zkS7PuFRAxql*`*Q}%TK&1|D2oj2lYh46;E7Nf8)g~nS&7PgEJw1zZ$$JVQJJg(s zbbE6jT{OJ4EF$7~<`OM%*kr&>hWHWbv)X8S`%qFHrk>lEnORhfapQHC9(+}GUWf*8 zzkZLSNAY~<%GixO4PC4Yw=d~-${g=?HNZ%a!IyXO&^ zvM{8_E>GulLRxIio4!;mv$vhD>Fpi6p7?9&gRp+dwl;s2Tyx^ zG7I$p>VNQdt|0QeRSpO3Otyt+yT+?E7qjs+a+hS;pl)Rx&Z;u1Iv_;rVRl243g5qm zQ;>5>R;H-MAo-RMV}Ek0G1@#IPqHfSW1`IlMrn9E#!s;> zly)%;0%sbc7A!2k-LLhBBoB7FNI#0h9StB3)=5Kv=wE5YM+LXFW{jo`-CqmML#ZzSOOY%gyEETrmr5$#mj zQ-4S)9;6J1L~XT0YDp)HMoGO?;_Jdhie}U8^FBP&CSnv?cO%Zm?FdBClpY#8{*?2@ z^gd{obJHUwub|cxXqm!Hg`YTua0OKah++1HDb zS2V%L0p-Z$BG?|ZamS1_%=hou09fPQLF*(Ww@S&C+p#sGLc=~?k38bALh%Yy#{orm z#3+}JEV1jMF9AN)F_a=paZD6fN#J3~M|a_0#Riko{<_kTGn zOZAOZdwaHarT_GxsOmOsg6HUXls=303g_*%ey2kJW>iOGI4iBi7j}zOIcdm(mmi(D zL?@~m1Ukc-L!5ienFlF*vg5*YHo`fi`mtdOUPSqJX+Pk`neJa0c@wan1T9{Az%@ms znjs?(@Xsk~VYk`%>UW!XUE~Pz1%FLcWl6w065l{gkbID3BDbtMWdj?(<^T954W^2^ zG%y}fq9r>Y`nEkuqnxd1|NXA8F#Q#=9F>wg<~teU37<`{WQ2&8`XkM8h-XeXEk4_tZXno$&R78kv}#DHP1}=`&QN zOpQdk(rSS+BPY%`ZG`c$xzE{t?VCs^W_g4(Qdv_vqotzaKI}`bUw^z)1L6F(>WPhU zBA{2N59~H9R;z+42vlAJi3;kG8#05?SLWL7OJea=+Rzj$uDTm%CFl)Q>^=B^f&xdZ z$E#i*t~1Xzozg3W_*O6bZKDPiJ?rZ#*gp_Ju?N;Sa1+D zD_Xh<#X4+;v}QSPCx5sPH&51c?}Hi=-sxk@58_lF9Qlz)v&Sv0(a82Fq~rzisP}-^ z#kHuJ@G1onF~h7;X|Tl^UAH?bxOFO0la=6ObElZBRT60D#>l76Hnf8aZ>TG&dX6VNcofYDEf~6BoL6+yCgwDBM0n!be-SQxwmiv!nB0&Boz2Isk!+u#dvx8nPaXEW(B#;e-C+av3XmV`09X$!5J(Tt+K zHiby1BWd`#GJmoVDb;GZc8E2@DQR1Jqc_#AKxcLU?c1etu?T;ZK^161%KlwS4bQ8D zO+vL3GG-r4mGgU6r|Lol-$w)ByJGJ|Jd9;>78&4t#D9gSmMS85eUXlucwHb8f|28m z*lJ~&OSuDrGpWLK6#u-qwY5}0Js0XYF5*y<^uUdW`r)^8`24SIL18QlY*Bna>`jkh zbmbtKDgyFl!ZuVAE%kQB&7|HSI45ENdx*ir!VrbYL~E zsjtZS66&?^C`x{^zUS#058NQCJo}P05(k#}_61A`DZ1IGc>-OecyNkM!#vhb;+Z+i zha0)oe1twg($ab*{q3&(jOlz*HIvI7AxETmmZdv0f@eR4N?fB9{5yTSTK<}Nq<>HS z#jB$~YVqGwJd}xoi&SjOPI73cQp?7qZnBt|S5JTU{FI)*_``{yG1JiI=u2B;=RVPr zqD2PWw`XHRT__(Uk~Z};?D8zXN_3nR=ABB%jw zl9U0@#&MHt9QcAcPz4EJ)#DU+CtO>eV7(kiiBFrUO?`DB{ifrhq@^!W#DA%s9ED}K z?7%!!#dNFZtu}_q?(3y?8RrzmkHW)GT3iQdJB!OVFu;L{$n@M;FA^fTY9#EMH$P9c zwjWKFin@P_kv-EP;$8AfkgBP$;ZbsI-=lQPSi=~hCigq^(4(ecA_?pMOhdY0d*{jrw>%3l;60fFRZKFgsC90Rqz=_+2l*BaSJqY*-X9G1^7UfPIvOh>}y=JV@ zxOy+bf0lw0fGHsOWRsl7BkTU;I8e!ewrp zOnuf4JQ#)6anr}?(bz*UtMBDS45cQfdMzJ-MUKAz2h2O+k2o;68EQ;u$0`HZm zl!{+2wPB7;@{pPa!++Xru#QJAzJ-dQQQcii-7|CRzBevMv+Vh&iTjls#8Fh|@tx=v z1mw7h;p$Jx#N0R6xHVmqbG*1RYpub42aQ68!S9ocbqc=JSevG830QG9@oqY;-L%{b zIao5AQPcE>H>bBzCY;fXE}hqkEe{SS5^hWfNfSX$oeTts)_->+2?Yf&nP1~nVKv$o z-bCJ(m|ze76e`1GB2QNZf4I0T)b_5PiKOvIyK{b|?L!nHBPA27=^DiNLC4e4Quc{G zkj;mcJM9$H=E##l%-Z})`q}PSc&$v>3i$-7RnZiJ3XYeIv%B?$BnVX#2UEjtO)0_>&mW2lDSgzu!tqRyuB9otg4GxUQ26nc-y+)-UE67PmyFop z&;e4&SkoeFtUhct{p<;Al4p-sm8y0B3V+Prmpvr;)qh7V?7Lt!=j7-8(2$hR5Q_vF zkZdX7&;!HAf(lCpTIYPkgjW~|Ni-~U*l$|Rakw_( zQOFYw9-aKBC8ubxm`R9Tv6K5%&iTY|jzo&CN} zj5!HbB-0u29D1SKLR@IfyT*(7-m_usNo($*&uyjrNk-SB%ya%fzS60iX!RoLR;M+>*xWGMIZ7rA|k3txdx1I07gt^X)%SFM-W#V~G zq<;}VE6W~z%AR+ZTLQ%lQZ6{aF z3Fc$>?j*$4cI3V&gNjM`MD~4+<&vL>f`3*zGSQ)f)s`8{@VWR;_=N6}x;z}6NB2F1 zA2H|OJ4@B0>*1>vmWK4nbC}5WI*l4!-eEN7i$VdOxxIA|*#w&oUmgYP&EJ=v6Z!^h zT9s@-e7NoC{<#>?C72wDy*g=kN+0lHZ{uhDEVsohc%dBYEA%=pgZWR$b7~6MjDL8< zTuAx;x@2s7xP=_CPwCy(nX*{ShKy@@{9&0gw@>)G!ZAOPPdmA~?n)#R`nabiiV$F1 z*2QI&q_1m)i_YcS$R>ZZ3ie(OfJ1Zk03CnS1MmoizI>D1h2`4+=%FT2(3H1QS@_(`SP5$U| zVvXO)Sm7BGuCA7&tl;8ia?N4hywypdO8v-b5RKgTRS z&fM;kQ8HBQ3KChsHX}Zf(|<#1NZ{Qh985oLxJjAY?xGAp2++b$3nj*i*}Pu-?ES_r z!fHoFm=|cH)BV{L@SRi(?@ORsjlP#|AOTl(5p4{e8oX*r5Sg^pP76-IKP z@CbSG`P5AoRU*=n1b;H{SoFb>=ciX7LT%n`%LdvuFJ2O?vbb(Pq(au)p*N|idYo|vAfBd8PGwWP1dJs^ zy~S?}WdVo79ZrH}}aj;c^8z@FNYk3H=uUi7xLNu@ogp-K*JL=ZGB{O~Et zIL=YH1f!h=2b$m0YQsugqV|!Jp%LrT)Lj+N_W{Z+<1f}BZ+EEPm02o>X5=yg6IEPe zQYc9=oR*rQSbwpp7nEfWGUn@w4J2CO#O;n?_FZl-*y@7>%W+vh$Tqd-D+t!?hzfCM z#&t0GBU&)6yP9Pn-~&3z&J72hJUpC%K<{At~IgKV=;w}hhwiQoaaQO zo+Wut5xucPQlrw$t1*URUf{;^?ChY=POHV5$|<58wv=iyy`r3Sjr!c|uiR|5JJ}c`E5@pVTrju10xM z2Q5a?5pvd72o;)(pM@=^ql;}Ojt14Ciz|bc+}ys!X=FI%%e3>!*$xJawO5AFmKSEn z9?BhpTesO~OaQpT=m9 z6YTQg*j?OqNzofRBA$ z@3_@s4+B0I(LP$YPM6w-W%E<-*5Zto}sexOIC!d}^X$BgiV5S8tRDaCN= zowy2i;24R>PSNjd_DFpy>I2W5J^!e81{9=9j)f#?oaX@}{fgYQ=q-^*F<3P?6h#~C zG0HdQ&w^i0*NJ;dlY*PJYLgmnrhng&PoVbp=b3Y*YeK1XuViE1sLK3%dh*i9r_m~Q z%yuQ*nGXWWee8Qy98GHMwGV=h*ENLM4RD0fwqc%2xj|w)eoJz>7YyrFy%(1$L@}2v z&^@5vf;!p0;VCruzHZ4@5?A+Ro@poI$q@dxT3KkAp4ED;mY!Per}#qIFn<^5VPaIk zv9a3Q37j%#jZVwng#5F&p$A=oZ)k|*-6PQ;P)ByAhm|8A6odA7RU@32@$)CFII9=M6?yS;cGs<5Cs?i_p@&X><ZD`J|bZiI2oC3D0RJ`b)|GAx$+S<#!sfK*{Gi z{+2q<7#6+Bfg7Sd``d`l2iukzlaXEKz!-m%8Ue6MMY|U?jgkpma!D*7D?tcnO<)~* z=)r7o+z#R$n$QW)8iwy=&$M@GXEBrjYJ+_+vrYuvMLB^asM| z{iVe7oO!Zff)|XGm49wHGqVl*>*Z-HtPZ4c_4S3z(g*fF0bi_#-V=?_`0;8bXT8M* zL8?3rXfRd#dXMToVl5tBSp33JUeUubBkXI%2qC&^_&EXEZ$=_gqRr>;+>WqwAZ9Mx zZrFno9X_TXOMmzdR)ts|$4VX>9O7N!XVq2vEb6ey?<=bF#bsmCTKNFJr@i44#KSN=rMbL25PLB^r@SoR2`ETI~egh z_inyzpw`I!w0|3%Hyh7ZJMMk!d}8SAuuv-{W zLxi$a3S;IrXvTGMSCg`8Ry&7#QN|6I(2(`}`dm}BpW{8-V_K#H0Z{LLHoNMx0~1a5 zX`XvZeFJ1B+4Nz4+@#eEu!-Zp^AL$m+!>IV2o2uAVSguy6V+*jadF!d^x06zePm2c z2VBQeVOTPz$81Tc1)7|ilV$c}@qTu?J7>aauZ%sO0HOqJ!Zywg6tjz}vu@~7S6<9w zCHcN=)J!;OTylSUjjq==NI`)oU<%{93%Qjruti!nKfYT{p6MfA5iMdZAzUDUc^V4M zD7(Dddw+eO7g8A+q)-)FYP+!$-^pp2s^v(Np;cYcXlZ_We`WbBh!o%c+Ob}&uRKDH zgI-B~x~i2R$VyMYS4Wz(oLF?Iwkr@^M49ZB-GxR4b!-(HI$c^2Q<+>TKF;2 zk$fN86wB*9{Yd_BI`}zgdF3rpvic3LM1k_1dAy2k3$!xp1#@j(hGn(_vGkI+Ad9w$ z(obj)W@8eUW*!6qoj2;PLe!=0$XK0^=wOW{->ial#8dA4)n=_e+S1t*t<{!$PkTdK zP=Andq#aUzzT&fLYf6n@S>)%jKOT4eHah&}TWL2uO2A4c(#wQIbT%|K`vY>gO%o=( z5S<=7JbnH?Pe6}3d?O{mrSOw>&dZ0?aIvhQjL1TiFHWKm&vlnSE1OuV@Z9S#;AQRo zIwsLa#Bw+Lh3}yzW3fLcEc5bg1Vi+6^?&%%7CrU6U48YmXg{{wyOiLQNMFt$Omrij z=Q?X?bsvA4nT9xqWxXB0&m`>bQi#wVd=?T2jzeG6vnH$IR7tF0%}E)-A@OC?a{l!3 z(g#)wBd)3(?EM@6!B7fY--MV`RS`(HZTtx-N+ux2fVD_=43IP}TJAXGU zoc3AM;16rV4bn&l*!rQ^%V^pNr6jgGYZir2ekT;r&zX`>rXTZx7Ii#%BRf-m zXcVEe|N3(8rQszE#`67Q3ZZ_Oe}6=y={|LFSNZ+@yy-bgLmVaJ=Z(eayAiMYitiY% zvV1pc#n=(|ke!jOWEdTTI2$Jj(-WE#4iu$$V){*s@Zo+LY7_GJX*W0Pl&L*(vE+6i zKC?Sm>zkVjB0Nm;>@mK;#I^?q{-1Xihr!+T)q>tq0m4}dCm3_s` zOb2t6Z(()Y;@tDA*#pQvTPoWxv9sFJ-A=PkxmU;x=YL535zfBWy3wAuCRlqzx3x-NWPVzmx%vUa5qzE=)9b{h(o4sc ziFM0me6J+*e*VY9?u;DqVMB%qfiI%&6B=}d6n0@JDOy;*xU|Qr_f#acKXZ3Ak`04; z{WJuFa^H%LATw(^*XXHX2wr?~5b|<@*YzIT|E`bSdXhgUNPpSxTlhXJGX>!uyztq` zNBXVk^j_$y6UR<}4Ub@A(mM_{8G&^s59SI(8( za(r>umUqx1w$?x{6}B21FN>Wq&u!pD48z8Hk2qCT7(>dkdLq{V`;bB?3}%-RlR*td z6b|9TF!T=`8{d#8*7Z1U1FwUhSzaJ4&w&gaxfLxTT&HW;xbCW)f zG3KLZbl;zzINP0f+2dgh+xu0Bt#YP^%$SFj3K-y!)kgmy}^9c1W>&Xs?ft6uguxwHOZpGMqO8O#aZi3Mu{s4ay3(8qxr! z>CIvz8ZhkYD^_=6;*y^u9vyOG_tFpGwSOJlyqf&%Xbd|>+T3mj-bAFug=akbT-t`E z^@rA;MNaf=^)+%>mt5C9Fx42@HuTq#zw4pMf`&Lxk z$dvnZVU0b8`Rs5p)lJHb?%1Se#+!}Y$-%l2f(Q*HkJX{x^+X`njF>!MI zcl`Z(GNG;Yj>gsS$SD-rgz4I1VJHO#`Q&wDF(xl7Hu17B6MBc4u-kK%M}^dOJYI2d zhckk;jAL1N0bh59tlinwM(=|mB!5T<=)jw;qs#bHkruMI0tiVhqe#n&7Zx~W;B@+N z!AXUbFnJOC@Z48oe6y-6d#66Zliwapy&aU7RQ$>(8m%xK)NqUnM_vb`>3BX~ofs?` zG|bwRl6aNkkR3EAE5d6akURcXIea-WPJA6fd6oz}bj}7nSM1>ZwBTgl&VO@_rvbbe zKb5F$ZBYjL71<8DWzwq1H89$n7Um#}KQ236n`B{#5?AmHSukZRB}9^|f#FL^1EFG-3!~W2wGshh7kN>sy6* z8f!@HYA}7<)okSH$7VuiD5u*u`T8ty(`P`55}yh-MPK@66|v_;r4b!;v_Wkar2>A zibO4>-)9elqar($8s$VD!g5VDc@!Wuv=43fF_v4E6L;28p?p1Z{U$tONR|m0BRmvX zUC*me?9Dj_&hxbaa%rXeCOb?4w zL|_h!ZgK+57HCg~&B=w{_w+=0_odVXAkX?>uN2lj|APZ|YfxRbG_1&7H~)digQ3bd zpS`q+Lg!XyhXkk6#DM>Lz;FzuuHj>pLtUrc8{Wfc3K#>O)=-0lxkP|#ek(7F76s}^ z-26{fC0ov4>wgOyVJ79kihHt?HIZAn-Z`BF(Gllsb-9r?6m2MAe|XhKV7fHmek5a@ z3NrUebKIy)ARP7ZAXSqekRULTc?hSEOuD{RY$Lt8CJ=P4E7i@$!M4?kM#aH_N^aE5 zxebIu;RM*Gv*9tYZVrXA(tsCKa#HT)zKHG|*eM5p1%K+1fHU}<4o$soj>l zi}6w?!{1_+JJpW=gH%>an}n&Sie%X6htH{-t^3~97F1Euusj?AbUBr8f9~(f87n)` zNfPZQNGy|5@wN^X*cDe^si(ifAsWSJzgd9HCx5J5%}aRVuGFDa!ceaWu7LIC*4OZ@ z*6r2M`F6%M$cYNO>En?I?lwl%}Fw`ZQC~gm@`Q>TeY=S zr|R5wUv^*gSN-bod_BBxe#6D8T{GR)$j7Q%i%s3{ba)~`v`Q$+Ja&ROY+rV$vT_&A zO)p3<=fsZe!<^Pf8KjE#$q@Gu{;+hJ41KUad(F#};ChNI4q%QAy;aLR9foF>g60Ek zZ=XoO43|AWLR)1$3_ z?r?B|X?I{0;7=R!l?rCH1$twBB|No&$APa`*eAR4etQUC5;Tw1CCQCsv6 zrh_#bSAo{XYQr{zmQ0!upR?K3_TB~@lRZ8{VJk{y34Qm%(seZy;zk&=aFkBu53KbabFQpRLGRs(gKpzVd1&?B+f=fig&=+1_CrCA;N<72_ z`_KyC1|~=n3EX_THQ2$_dYjUqpJY!$^%=6S3-&FGZKvkSz>T=-RnLD(EffQLGS^nZ zr*d;B%tZTRMf%0RS)`-y^2<457Aw4eX(uE{6kJGypBvd7!^}I&hSi2!P^T!QKC0Hv zG}EVT!sFDRw+63piQujeI{p{nab*aSp%iWo>u8N^(f<8n%^}MTY{^7oN5dGuc}uTI z8J86X+^#`cHaPSyAJX_};aEUQKR<8iLs5pRmZHT20tl|d=D~jPP_3pSr>uCDho}8;AY$%L7|X2H{8M@W5&Sw!ah2BJe4JKuOlswONRh8d8s>YriZS&BIO>8 zkYX?^S8VWdQb{|wVi8s zhh9zoq4O@e%i>W+ehlPJ68qDS%1H{B;lUZJ8uVb=V>@w-sAYQl!L;+7kxB}nRmDg1 zR_^jcFSigLa3gW#l)e5Fd=E~ihQRdF<(w+FY{*2B#s@4r2Xh^7@vd0x-X53bgE}=& zp0va|kg*ekSlv!32bs-1Gw&=v=CSECTyfgD{z`8ik~XNwbY4;6O}ow!r`NqCLbJ~v zmFD^4-`c7aeoo8Voxk9tvI;Vzk>w!Aos*Nr*5^?2+lTi>|C3`LIqr4Z7X`8>;X?iq zH6j|Ui2*d!0+o+=+&-sAE7yWv=6{rU#K_J!?1M4onedJ}2yz~j7p^rl-oH!pdi?=$ z-pBE23?cwHO`2#mrtJ`s}`J9{m0_abX9lE3z_! z2{Mf#)6J1y3S*rD#x@~C^K0A-`-r}KmZgZcgZ!X*`U7Ghd8FNcaY>8M{~hX$e=J_= zZ5Q}L5(P^`C6Pc&R;72P_-i4rf{q=8_-UhzF@(eZI-r>`kdYO>)x*Mw%>Jo>V{GcI z(GHY|<5~J^=gvbLr}-O1?}1%e_-PEIrlL_^>e`6(uEm35d^p!Al?CRgMe@hmzQps8=wha621aGl%3~y!;2a#qakbHbCjL>In%>qt(B~qetO{w{ItfA?=TLS>m`2Yk)_eOaKNPK z@GA!_W~l0kK7OG??qUB0^Vza8%K_T3NJDJL@*w%#N^S4rF%dNQCe1uHiG-9d>z&0^ zV`*^me{y4iKR3kY?+QvXR6am>tmMNiKZ5#}Tdsa>>aiB|ZiI~)nFwf0&5uJ<$tvoLEUwSYG8wQr$W|2CavGCD=_J0r32P#dLs1SYd4PFtAc zlImBbo;2eV$e?sq%FzT=^)?{RVRJPFrn~5C`I+x-Gv**iV2{%KqYhkh9n<>)p0oio zC-hLX_sWQztdY;O70eMjj_rNyrg##x5zkayO>|t(U>w|r85(DWKUuMLnbmBQNw;>P z??yHet!y*`-?^W7Sa52a(=SA6|DD%xIHvJVkcNvDadO<%ku_w}6bt|-2UYE#U4l>O zG+R52Y+)3FZ4ajmunrFCUw`mAX@e@Mh=lP%?Y60qt5m**=Sl2LnXKe=wLbI>82!x;cun*qra?n}^U6t=0Xm&m7 z+pB2^Cq7mAZL-Su$%-T)3}Y6)kA1tMG5vf{L!`R*CbF4tIKcBZ$!1AQpV|?|yc$7~ zmJzhm6-T*DI<>X(d-jLm#J-MDPsM@l#6j9xdpzPoVn6U4hP69}E8k(H$!Qf#6kbw9 z4dtju;mbWlre9Zz9LtzB6P%iPCY?2}2@{}*)GuI9a&|sqJN}t6+?Fndy|0y$CgHs* zi+oO@q1KA1445CBOGg!*0W4x3 zfkAR{RUX0LKKm$=isa838$=h_k8D0hMVFv8{N-Qd2b3f7aI<~zc26HxRZ5IJt_0o}we@|4Ka_Ge+Cyot@ zdy^pwn^1e3X(cy1MrpL5%}6!)^xhoejOTv$)*DSmDy`GLq;oR*D|$9;3k;kd%LS)U z8!#*1_zI}COvevJ`W^iz*xR*vtYxY%$b?ltXNpZy*BF=TKCS}tD+Y^O$r~H4-_4I@ zx&BR&c@Q$f=iMr59|Xmkn49l6Ia2GTUSuAxmaL#?dm6_$;?49$3OpR6I*bIr_Vl;; zSeld5fEV$^bcPzn@?K1uQuGwJ?*%zt4SeUMWj-hJokbve7@Krzo`d|3qz5It#KS@2 ze|yqi%*0SxRpiEz9KC&dz5JR@8k!=y$e#K#+M4DJTr3Q@4tQ4-u%n^>6B8M_X!86| zu&i69U^kx!E*3sX>qV|u?UF!qxiFEnwcA3NJYYQIMnyH`b(l9uLLCn2(X1fr0+=4{ zutU@Qt9_Kn_(DRzQ0ly6!8!b;g0#^II#EuTd{5R+L6+!X@}By@5S35t5{#g9kQ27$ zmUr~$KO04thn=P zpHLKG+K_6uhpYUn)JL{R?0sGUgnNZ=Z}ag-TDlL+{hl+ptkr1(GU%9!=(v9eGxxewl%~Ue&AST@#1Z$AtmSf6Q$hGt_2Ugsd zLVNauOL$8$3wvb-%#_2IGGNid+Ym%)S$*Ba^Nrfh#SVTKT}SynlU+41hmnd?LwR>s z_BNVlm0N%cP4VJ;(9D)X_m^C}nom!2+LeCJ`_v~7ofCT(%6}7sZMLgs4X9Yurc7f+ z>WSWcm>|#A@Vs=yGB(8{;uHBaQ5Huckk#1)*;gxr2(%4PNp}xZ2EhBzLQElLD6b4R zBCz1uAg-GTJN~wxl$R4Mx6H$);3=?IgP8t3=IN``*e{=kWk~Ty`eAV0@zzT)v4fA4 z9jfac+6#|m3)mwMajMw)gpu+;1z&i`(em=P*(SGh6^-@Z+FhYNimTgl;-?#kF(zbs zxx0(ZTmNY{Wq18{8wHF%LYgsKU@sbzRngHpgwE?GZphiL<=Xx=_3)MrbYg}w>2ips z+Gc!sO%(c6cf`^{xW!_}Xi-oUjF3d?E#uim8~q4+DYT*Y-TUQGr4UfWyNOcx=Bp~D zpe4`U{8pUuH*S-NOa5y~H7MYHG-X*ae{vse1GkicHAnzK0ujhTz29lx;7l+Uu#2V5 zIeH8AY!avl#pCC9due`VxsF1 z^KD47?+UHI5-5n`00`4Rsj(<1nsH2f+0yv+=mCZXExeA3#DeK>z{TVb#Q&Ek$>wSyazfe2?Xz0ra4ZlB6S1VcH;mPm zIP6yPCA zAv4@d<8tg+{`~FL;;HhmC{=6;aTHX z!An7K?qHsx-<#`NYca>yr%o8I)3!%q)=)n{UH^m5v1vaFR-D&55RQs5UDD<6@bJPI0kdZe=`e-^`E80SvLlsu1Za(OGW-wOD_ z68wTgpra?YSLxe){Rlf=oQB1V!*$x02uzFARwnEvTF;F0C?#|kEjQj-;&1M)@xnU& zd^p9G^y6K)39dAxEgy7&OYFuEht%Jo)i$d*Yzcx#(`jq8-ip=1U@qqc^Peh3rSK#o zQZ1&Cl4ml@RCUB*NFEyTpAuIgHvztK6cD-hsQ8V-8ZbvRwD-{a@<^@RladZUf4-k% z3T#_n>@gQ|((QtGL<$G2c-RDy2mQ5#Zwe|K&#C=|7szBXGe>@H?7*BQWqvOhFCooJ z&6=qK86C-K`|oLNNuVa>Q;V(M^UTBXlIxMsf(9F}$Zjv&%6b3&kRt3D)&wxy+KbdZ z9f=yOS7920fqtA}4|owwU&W?m95YSO^`uiWBsbnxSOodR`)kS06JkA!b?U>{GRa)D zOZ2oJH(&=^Zu|N7Q3^qx8_C)3xEl3cE&c7McH3`?Tm~_Rg@CpY#;RFebo#~gBzum_t#xqA`=z zg2{I5#1>Xq`rIJc*`uH>0rE$NjD1_maAq9vYv*i$7lKf=BwCY1Mi+`Rj#Lk>r`iif z24U76XRxW3#|=c@(pQ$Dk4tpstH(#2fBHc3@(L}TgB$Gx!jfi}ZWR#n&KOL`o^BHl zuh&a;h)YlKRUZb8u+zXnqfQ*!KK%q1pPDiL(0e|-!!4AKFJajY*=P9KaRHKBVb^#ixhuuldLvN; zoBwT6@%M(7e3)X#EOX9b8hH2}s~`=Xzj~^xeP_Z|933JX5DM2T|3=l0On@TeSL;2d z9p))u6JcijBT$o>M5OBeIwdZ6pr6(+Z+8P1-{%ZC3&mWwwA=<(tEFO)n88alk?L(n z2m-v3*Rs0*&e&XQAI9FjAHQ4R(bgZ@h-9H&@9qc55_XHDzz0umb(pAYrWIqc z^B=4;w7R4|>Jvp`d3v?xdlI@gr^P`la4WFI5|$J_zx)qd(Mk<3rdB#cY@CeG z`7lQKx7apBT{A;xO1}E3sAT-+X(cXF=)Z^}auK`!OQ;Up;+yD?X^2FqU5UFFE2$It zM=T%D6*zYI8yEg+Iu1d-tuPl0A6c6+&X)}z5s9SrpA@gdjE?CVlmAi!Tkiuwx<PF1X$@xDv->>zwUGaF50(K39r06K82K>e4URI3Qa3QFJpOUS+Xhn>CQZy7gQrdjL05sG=z`Iq zW(Y=6j5G=x2tlJ&iO1SNQ$r3X7DLyNKuH4XWumFW9t^|>gg+9$Ypzyj!22Ik85=iJ z6l@X|l|{z_Lw>2LLUDO^CKCCi0DV*$So0FBP(2(xaaK`nnGf+~R~>TF391V!zj@h2 z7{ekQRdgNeU^!7+X0p<`5ws>XQ9d#j0T!^b@6i_8EG?bFWU8qJ*kW?&#{nzUAW~o= zw%?4s)fq~S%9vldHU*v1=0Zg_10s~1o{pdcK_)_4X#&oco>oz7lEFZ0mO*6gOo>F9 zGEy12taM#Q5F$ENX+TDdbRmm&C~rXv=ZCR&m61wOpEa1;2E5dwDuq(mop_aS5_=zy zNtigTUSQ1+W5j|{t9|v*lvv^xVh=zLBc4&}!pK@htonu->y8K`EzT+mS1&_c4vxg= zM-v6V#(Ysi12w<27^+eqiGXr3y_&2IJ>`*kA1t*x;cU|kIYb1mmqv-@1Z!QM53v?O zy+NGzKn-H3sqArvqKeWn{aJ_!Go`dF&)i^RdtkeO2;UqUiNz?l3`o={-U48H9JDBM z%}>l8z*J~Wh@ACk7^LG^NG4b$Q1YjkzRlI$+SW~fS z=Hwd74+h_|Li0`bqTQe|HxzgJ!(a4TsbK*xpPoardyAoIxAzu;j(81e4x{)jd=b6o zh*Z}@$P|Mz18vS6v_rP(M`tePvTEr`Uhotf6R=xH2}!lrLveAo6wqF(&~-n3ik@H$ zmYYv&Z9F;RS%aSGzkiBWpYDQ3)an4=&$CvnuePr%3g=`Bx332`ndAjD5&Y#<%gOa+ zn?FZR4Qcq`B#N4K4uZ9xJyoz6spQA2(Ol_`jl4CQD#Vj*Cv2%(O+pR&PBQnoknw3uGEB zt%_L~3JQ7uy-5auF5ZB*m3L1(3C7q#QIPaE|T13F&^h!wN@%y^I|AO)P=#WcDCF4!%QML4(I~+NG`?!62 zAZzQgjPHDGL&>-Ne!|AV?{PB0*Q2wKkk+3@V*46*j|xCm3uR};Iz=7>;p^@C`C!DY z7t-^5KDSdppTfo!46H>oe8Bz1*$b7UcQ^07vnh$H|EbG5!K2+>fA6-C|0A~GYiTEk z$@4V4Fkgi;U&Z=C;BGfxz!&n$(}llh`$$uHuTHDgEaF%7A~%ntA|WBsXExTPd#Ytj zUJzfGc{AW4F260e>gwWI{`p|hk;TABWn8ocN`kdKID84&kFp$n?A=}BMDivS1@)5n zgA*xU{3*jPz`vzP@jrHeT(ckl{`}pv&!O6+tD!j5O zUir$d9f~>z>$3n6>#>6Dwfw!=Ghu6gWW~zJvT2};#iNLZ%yUDDwTlYq)w@W6Rsak0 z!FVJ;NEynE92L=PN*4D1h*!k`f@!N4zUv0qK~>Z>%E`Y%=oQrF!;eNQ?}ZwJ$%{iD z7-%wa#aN?AYAd%?#ZIG-tEGR!Bpz((|X)q9nR~yn#yJ$OtCH#K*?O$e@v#ka9^@wp}iFCjp@x z9ia=VN~noj^%#+07|jXx5M68;+$g3Fo}sHU@qeJ|?8mI5k*7m>J>Iurg^ z42$M2g_H!gF0{^;iFPD1pLgjcCMMK(W1WEnBHCKY&_;=Vtujw(pOi(Eok%UeKbCZh zE3sgePOno#=_$+-C|8s@Rx~F{ZUf-Tcu;kTcizEel!B23trZ)SBmRO-CN@CZEb$7> zgQ()+^(I{^3>#}EwOP>IXP`3-ByV_~h9Ha_PQzeJr!hig1ZVjzd(QrH!g{|ZBD1c1 z8gGZ+KqoXT-DVemPhV?{Lt%xNM!Tv07FiQeO71^ssL{G@ZuWMqiuoGsD*#Bzy^&3- z&;;~doRh9Cl<0k~KaqP2Hz=LQkeY65&`uUez-^y<{3}URwrj@OuBTX3$*{Q;uC|+O zK7}c;SrG+wJ@*TqJ~(EqtUYd`NcH&-FRic8@vee7NDZB7KoX;d9@RTC*{ea^wqR<$ z5yn_O4Iw;b_Yc;eTgi34(mtR^3U`lWk`iiMN6dt4A6v1XtR1HLS-DPu^iPr04>pXjS`Rc!~}KZ>|z!Jtz3l+78@`4%Rj`N!76epuAq#4N2P@r(@q9w5c#1HbE+An z_=(*y5VI1WiiNo!2wiYHlQu@iV+HtIuz$Jaa&Xf+4n2FmzFryu{5L?SmVu<0wsgPE zBF7}+8VZ=FiX-SUxk@8D#bH@z4gN>xSEYiGxrtYU?n}``GYfg9XDg-+U(81KSDm_q^?E#c9oltohtga3-YEC#>2AM9qRWI!>wc68NoTarWi(J*2x|_CF zrG~9X&D3P8b2tM~w+;m9U7XiD^woN^#}PSAGlKqA=}*Vnv1rivT=`5V4<~1DWXCle zF8d8QdPG*Pn6_vxlxF|kHU`-$=sJwch}E9v<)4$8oNINr^MF;*zi1FD0;Bg41&(O)Xq-k{Oz%$m{;qW=u(5PtKQWH zKX0=9XTs+Lep7%+YG@RzJN_nY^;l7JbQ?8l&fuW|!Cn*-|=IpV%rRJqqku@T5qrNg(9xP+!@M*-B|~ zc`!>S`|S-8g3Oa@A_%(ljAZkKe2`%Bicb@6vEox|cp2wcw?DGfRF3f5TQ~8zq~+3z za<$aHs^dd2JR9K<{{Hc`m8Eo&W+oc6)^`$cDI8IX!YzT2+e2TdH%rkOK4k5r^bac+ znoG}SgAxdV(sc{a#i7m|o+6A&)TOTzov?<~Nt(g)opG7ZNjzl@Ig;6Y;w;&Zbz__) zzc$cFQ?4X=u*4Pn-Z=)Mcqh8GAl~$I!jY!nf**29?8mgGx^bA9-SWVK)t_&=n#3? z<`vzKpw_a&TFbTGfP7UB{ta1Q zNfp3Fte$btM$+)ZN!Fc|c6jk?O3_6Y zFaIMh-Hygpu5WwYY$bqw&4MV7orOJboF0M zAD@2GyYG>E_%HvSxIuLqE^96Kvd`B>aGnlFkOuca;H8)$ZN8N7?VqBIAo{==LgwVq zDaqTQb-$0aCf@29%!grfcZ22S@{7fqclJ6#28Xm|iKq7We=p0Y?+sb%4;OOo+6-00=KA{T znolk*+;yKdY0K{J`T#|Odh>f%%_U&-v|7|r*`ood?^g99IXUy7d1wYT9KJms=&b!q z+u!LP=GwU1ayQso_T$*mo!JpQ`aHzhUEJ(S^Ah|}L8_hQH&8fjY#f|~2OF8ZSN}L> zH*{I+3U%mSsNKPsS88YuSZuAkij($6Y0Ecv`FjFeI?)}`yDp{*HQk89a2k+g%FPCsS+Fx~$9OSg%{ zPsp%stI=4lCG)*4C-3`*XYpd^d)K~WKtJ%l$@{hKKOM0Cj`;jGR~~`nZ;TTfCY#sv?7LNJf|gJj+Z()*lDSKJ9ECj=^qNZYByCcSH?Yl znMuF>suz5V^WS)wlA9^W56s~p|tk*yEsj57pJyD!b`XKwDzsZVktUZcHt z(}~dF_+D|X`eyo)I4#SA$ z?t}IC>WJlHRJ?pmrYf}O$2uC>JPk*g`2BICcVLN5%S+WV+8|f^rszbX?VZ98?}~CiB1u= z`Hw*VHCfNb@^JcR0_KVikt)kyOOwL^KEkz4Yt{I$>fjP*J6eS9YM;--Pq{XM$H0V~ z-YG}sX~r-;fYdm0(w1{D$Hjp)r`zS>@Dl%U5g<@URkG$7xtXP!%2TQLUkwok{E zoxY63!#>d#Ep|9-=qs7`9(?6j#L76f*-8g4VzP4`On&+aiBd?e$8$@3Inm72IGKGZ z&>Ws|%#TI{+=T9R=&;p4@3@~bIB$JQ2L%7r&_Q@O%-T<{p|dO@ak5H3wC&ZtSA;8W z-ofmsNbVx&`EP{kIM$P9Ell}KS^}};50^ou~rB~W_mNVQ>|J5D~ zJ45F$#_-(;tf)BrM|=?OuCrUuxNBE+zdai<-?`+i1fWl^_WhpSTFGxbF=lemaGgk7 zAgi-TmbGo3yPiVd~taftMgy3J&#w3MD<0HyfhUFhWNEf-^sv(k5~SZe)xHHQtn93fkvR-+xR@D?UGswT zrRgkJaI&V~P%Y@oHh~?P&&Zfn)*SWx|H3Q2AZ60eTK^Z>jpzSrYs3&NJREHQPh4aD z|Ki#=X;DxR?*D-qy>f=Nb>lZjFal=lu!)(*#lqQKPjpHUQ9C^l$SaIHg*S>|now6Y zeq&%n-k0|F?BXPKqDx$>baH~}<_+#=y7o>LHvbfbB}gGQXzDX0h?yHPr6?q*(>Ob- z=QYOP+Y5{Af)WV_R;kA*YGjm#a8v6kO_m3|=YC1H4b77C-`Pmi7hvVW1ZgrAopAiJ z>gSV0(T19n#kEx-W%($PFnNddonQtzm+Ho;%*;9QT%dJ|U(1;aC9w>Mk;@+0;&Fw14DTWXNX}qA(EYN^+

wVvX@N?`(EqEOI`5aG$8i^6pkZ6ti!n^6%wKJwc`#r6eBE1! z(QsBu9q{+G7lQsYB@rdDcc)I{KnUlqp{q-6g0j@FQmy`#2>R?~Nr_O|1YFFsv%yX&SM9_<5|I0jm#2_Q}cgj+D-*w?h8H~L0WGJK4m5t3* z0NEJ|xX=tSKC6?gq`-lxoWSpjJBc%TH=Sz0i8QbrGR>Zi3c9uvHo0TN2%h9Oj-YT zTjXSQ9zV-AAt}OwTU~j(&{t_Tmg{uYb(g}l?T?6N+Wj~FR{t*)7NO~I5uH#5}CE2_q9w1f7AU}CXn-NpKl=Om|e8m zeQB3rtzRzj5Vt`no!fnQ$5yFp$6==uq0i_>P^?M*Zh;-;Bir4R8E%O<#Q4|bWhXw% zs7vcdqcQT4ek@D3(RI?(KF2uzatSnm>sGYp4{mAjALW0qQ~TZL6{SPYg`F*P`n4wv zhyV2?L=qVi=QG-pFEK*`=>M2FzwYkasSSXQl(osL?B9+%D^C_L=|x&<54rR&)h={Q z>6hz12AI+J{_Rzq#~zv~H>bm$_lt*cf3tmF25%hG9d~MPtG^~-8ap-u{8_4jQ^#Ig zLJ{DF!3=r$=dy>g14;P=K)iqWFR(q5C;$`k$Okt17NcJ))61aWhJ{K=G;_E@>Zo2t z!x2!nqzKTi-PNaSGSGa=FK~w55>rReOp54HR5y!Ss(F8_A}wM}cYNMdnX$}HocyHe zcYARn&RCT7iQ&P1aH{Jw?HdM?pjpPz?oXfkmR%Z?H5)yTJy@!bx;iHKZbb!jYdwbR zW(_mkdaPM?Ma>9%QiqzPH;xMiu9#@#)%Km6t6J(f8@u^S*0!1K>32ZUzPyVPlnoCOvq(uI#`Su zUM5(ISt+VFv8yJ2$QP>PzsFsEZ&y@h297W0Y3ENKEj#uWn}CbJ*Ajt$%kSsx#?8qH zB%-6DEq(RQE!~sGWxw8o0R67F-H7TJEWU0p&v>~gPFC-fO61aJt2L{mxL$)|$8sjs z62yihHIrLS`&7aNikAwP;qQ`h_C1U3$L226H}cXXGT)E{i&vJ4chY`+VK78?p})2t z_k59H>isKc#xsH5u`T?BOTYmePNRd+s4f!l&O0d!a=(^I|0-=+fc_luejD{eNGnFqb1y-ZP6A z6k=sPub84QCFY6~*}@h0S7Q}GP1iyf2EG)yQFKlFn2VLy2TwYGV0py`alZ>be}S$) zW4)#;kAtJ73;2MdgR`=-rmOjY3S)d5XUxPZ#7rvYu8!_5rsl5ym#3V(4~v&RlaGlF@IDZ9}LR z1t;;mY4XR_{ebM^q1zG0D3(+i-Mym0k^d+C!Rcu0te{USdY+PTjmr7U`zF2GM{vY(zVhHM#WsG%<88KL#Q==FN{JQ;5=z7?WfDes&(244c> zN@Eo}d(uK^1e*B(Rtebch?CYvB(8K4y|cN?i+S6XmEBCF!7v&23c>&->1Bt?NXO!A z*^yXRNT4-_55fAgkKQ$vEP^Rw{v|stZ{`k0ct>Xf?uL(UfKG|y=q)mN=56oUNF`%D z(Le_O(`5ti*c2cfsVqq{Kq~WW9^+!O=pIhs z)a1|!ZJ~WU1BD`r_gg|Mrmhzi{y084&$g~L?X6j(l|o#m-sPAg6AXhyGfT(V!#OGKN>v1Qi^}P4OOu`uj z35ZZZdB`)G#P=^hDrO)5LTT-k4+T_ zwEbMziVqA;n_=aY)d`%vD1hv~QZ$XcV~&ie7MpEnDS$O06$grSIJEl+w<&cxAX~=Pg8ChvOE{kDJElWpWRh-kfXq?54js? z?J)h& zzq5i+8JQY1u_Vjd09o5#go=221)${T^-rt^HJjp4UDB@s5@OG{U!K7r$gQ6T8nC1T zu$ruR&vZ(zkreWi1*Z5HVK`OjZLDkcsTfa!JhYd?0# zlxW1;=0YBh-1#h9kmsF->&`_O^UD#L)e}1pW>jnqeEn*DeSn4GY-hl^Scl*uE}HKC zEFc8apLdY`I`By5HehB$V@gHBo-%0siB(;r3 z6E4f@ur)meq!mZ^a6X#eKx&OHV!69UcimgA2^!}_m31L+9>~YQX^fQU!zcFbSKKLx zwW4TWPKrt>i^k3M*=TyG6A{R>k{rp<=n0@#S~sO;%Cz+|0qv>U(hiERJ2 zM>@LrW?y9SgyQK2K@g3ru>QX2Y5Ijke*kF1{xbf$lJ+Q-jH}$kE zcFn;Wg=QjtajMSwX|#&oMUM zMyQt;tnw3bU|}Ll;sk09EjIAomy%#$QV9)wE_w$7?XlfsRPr<{#Ah|;J(v~DVbr_8 zRx&hJ&~{<+z3RLmK4moT{p`CpA?D9`j>$FvrbC4#7@!i+$FQT2U~DTGo1L8yZWMt3 zhR?S&+D;1kgx}cRLpub1$F;;5LIDPjk&2XF>SpyB{%Kor9k% zC2_flm4|fKYPyI_B0p6yQ3sa2fev^vT8FPmq81=f;HYoVnS^k{Nc#BZdg-uzs(HSP zBE0SPsmztUfWjXdOe_ z36#L+>{(3B30`90JkIT{eG%;Rr}TVRG)oh+(=c!kc#eh!7kYU-vsA{$@;(so zkq!s`z%{ZnvFh(pY9HiwTlQo8kuZT9mQ#iS*~~qz=07-FgamTSn7qI5q#6{4J(K=@8bdf>QHXpJuCk7OT}7guGHd9?bL@Kx!1k=Yo>2tbi|MTaP-&RoIa1X0c8iZb2ctDD>eNZ+y#^{Z zd|8}JiXYk))%f>DM32);x;|!%HF8L7;D{qxP8B_Ft9=ZX7i^Uh- zZ9x&tAvQ|Jq>{`Zq%JKBV=zlKHmlR<>~MmVc-dNG&qiL+o|>v_9ODr2!Gyv1kfA^d z#F{ZarBGGL3f97u=;5%lVCO={i||0YWO8>J8g7ZK3J$_X^3bqozaP>ti;1!T{5c3K z-2gwP@*j`|m6gDzBMxGQbwra#kl)pTm}M9mX~yQrgt zqUAD0$-Lpx>oLR`2#Y~q&YzC4!v%+^oO0~;+B--N=WwJ<1kRF=5pL0Suoyk(I;c&M zev?l0w=Zz$FgS;4$hm_PtASVpDQ0xIb{SD-Xu@F-)BUg_4x(1{Vlay1yx}9piBfy_ zipU%#_UIgs_ShV5TyY!SdPT>!Kei-dJjA$2J2!EbudJVWi*R@HAnK44UW;FU7HO6! zQy-QW(FU+WM&XqFdH&~Vj_Ej2N5S7#4V91N;N`S=`Q$UI= zqPygcsebI}G~25+;!3;&pt_OxEx=>IZNSnancZKCe;+lImdId!Fb6Hcc21HiYUD~T zeW0RrQRxv_M&A~sgU0F?blKz#{FHd7myt$Y7v7ET&uFS5^aht27yT!UxhW;t2!weC zEayLCRjp`uxYjt7nAY4&0t|^$ry&33{>4_ zvNi_2TLz(^4<1Btq&WKGIbGCClOi}$I5^+WRfos?9!qKy!4Cro2*s^xonnq!Ahq2$|H zIu|Io=bK5S(mW$}&eJGF{g|+_dZ<~Rvg1HuSKfgcdpP`S2>SAv`br=TPI@GjE*zL3 zb>aXN8kjZJFC3Wuf2$l>82?p{c&R(#z_6*-n!tDf7A6kn|GF@q(%N#`Y(@sW=sO@@ z1#vtvfeFSL%=5QmQzXi5%HfhRI1o@0REdbh!wCHHAP0E6)xi=-3e{iAnBN;9g9#ec z5%zr1O^;n$re1b?#NR&LU^4LkXkqfi4^vMaUhi+wr*`OIIuJi>4LQ6hCjqVzg(dL6 zEIu5lGrxq6xX&;0|Aik&i9QMPnR*ot*LCBSEv;JdAbjL9eBZsT%wHNz$(XhNuIG_J z#-*|dT~Stk+1a@&3LpQsS_-|(^T8}{nRR^_fvszE-Isv`1$0LfE}e&|FllaeZq%Tr z&dYMVt~kEwNVlVmX=_~&^UXdWZBfWwzC$j&v}9rDV7YZ`vZ3aq zi_qLv@Nx%cR2Mb!4xzU<>n=mQFKoqa_F@Z=_>B_H*uoG?S?9%mrp*-39p zeR+G?P)6c5tSNw>hJ{ zAYp~qiX&%e>_C_*hPjs9+a+KuT+0$|dl@Gf;Ut1OzSaVkI8IOYdKDUGuS!ki;xl@1 z*Thd^abCXkZy8q*g#8xUV3**|ek=0yghRZGsPPQ4F{6zKHb4o2wR*w}&H+_+Md%0> zhOG9W%Z-^|gkWwDt^khh+Im63iWZO_JRE1=Z#K8$^>qw*}o+rXiy=1|uab>Pa!sT=pmchR75Lb2v6KRWf0AJO!~9hLRVnync&RwDm5Z z0MgRqAg^2j0C31bw~DSJ)dn^Kq31*6rZX~}bTVD0Z9sEEn_qA7%Km+{7*#5I1`1Lf zFPqmldx1QfpxmkvFlX3qc=UW7Hp{j(i>f3jxI!Ji!0Xdoo!GD|w}v9p_qI`FgD)i! zP?QxQ0R!U8Kb?Jq2SkG5Ku&hS{r6~sg$Qr>8fe@P46rVPcVdT{?H!8Xc1Owz?(%$O z!807?hIT79bUt&Tk=pnzz?1rf7i8obPatDT-oh0v<{{vjzX&ZwDDhF z;{CmH>3<=w@yxxk3RJ;hSFG^f3zj{09v>9pd{ZC-SMdk zMjEx?dyW_tkMIpj^X6z&250+Nb*XJ{B~T|*%0`CHNqw2|y~UxUZO)@8O)UH%jbfVy zWBSKTdXL94d#4@ECFhf_6=X>PqYEmznxB^K5P)!fc-pUQH%rhuiyNP$Y!jI)3R>0r z4}qKj%8sKSXpIfWyn5PfS>zm=)=lv<=j`p=^KOp`EtrK(fgNz-#r>$Zre4WI9w^b6 zSJL;|eA0?Q0eTM%*TnuswRnl2wX<$2ovE3!y}eigUBh5q_wXs!>5zZ8VQ4SH zJV1P5u`>bIR{0g$YtP0Z+ESV)+IlNGw^ zXgZ4mcOD4;GMN#z3q=6W`_eL7Oh0*-0MLnBiOhNG`MX!9r$F=l4fFL(2i1ldGD+-r z`HIeY724P{Zr$r}lQ;ca^A-)I43GrGh`Q-xdAVoU8w1Flsf_jG=UI=0a}-ei-#I~33|vmvIM>53-kC%6K2(Z+dUe&d$Km_xBtZAt zjN*bJ-hN4=H&L=rdy4+fKnNHQ)qRt&c;bVRyVpWKxb2<1k8UDYNZfO9fGf#oMok<~ zc>0`S#)IC4-X<3X`Ri<;=Fe(s)>G|BAO^eFE@HJRv%a1Z(J!YWiZ5t&Ovw4VRLde0 z#KK&7CkH>IJ(s+=0SD2KK@iR;zPyy++MHGejC0G{p5^Bei7|sH}G-uBwF<37?%By4l>5$m0lv^Zh zmSR0ZcA@&8tP0ru57O*-W3AJh3#+;V?C8q9M`Lvdmqr%R2Y?cP*ujZklIZjsAL`9aNKxMQTOA~I zBQob)9}u=1R|4x_7wdW1UjU&fwM!2_^j=y{TRiYU0z#Bke%!w3R$NpIgC?%m8>U0= z@je1KO7EOj<1^9B;L+WI=fHH*c6babcq-300yW)OZ;w694KMyzQGc&u8CO=8fg17| zSOIrCHwUA8&dnrr4yxn}r|FhdctjhRNgY(|{tgjOYiOhDHk`?YQ2;_tNsN2E2$@Fp z%*yXs{x?rh{n3eVo>`QWNXczG4V$J;Q0P)La0%7AR{4Vql1pdu5Q<^`W%OM?Ij%F2 z^+;V6p18o?3t28soC7rwEoR;9+h9&=*JVHC=&s8u8k}3$`Rbu)s`EQt#Xl3_S&HP{@g@-Mp>C|0DY?7q`@JJ14Y%P0byAsVh z9b_huKd!}p6A-~ghjz5$UDI4CD}AOy+;mdElCu|fWN)gak!k5p1OUm-CZaCg55IRS z`+=NE{!M~- zlV*r3>!aP87l8Pv#37hUzn!|3uV`>-^+S-unNQ%IebreJ3Z`8Ws>(ymcIYgH5oo;r z-vN3SR#&1@b!5R@k-QZjeTeqQR4B4bN2!bsYf2^8Cc?iC1uQ%dfo~?l&dSWYh{VlcQi= zdhkzjk_RD(*g?W5ZH$aaPOb2ayg6Rz<{*_QIsmQr_7f{|R3Pnl9*Rst9=TwC*=H^F zy+%3uht|49$vxIN?`z@&g@TrdcQuGSgdmO-2-%XiL(?ZP3YN3@%jYU~63XUesem6Y zpUrD(rZL@VYlkHEr>dbJ9mHW!BgAjC;+D69FD8bm+(6tnmh4A2ph6fRlX@dy?YXJY zCqUK^_N11~yR-$%9{UHQm6lT?kW~Us7d$&yDmwLtZYA^zGdLx|TH-5^l@jrC<2+bi znOM`O(xT;`2RZ_%$eids$|FflNr&8}CAnN>85wupwq zHe!-2ZUQ=5N6KK;I)r!y2dzO66db<@szq-F{~uxdJfqZIOiSov`bzgAEpmn?S-rLP zes@|Aa7#SK{P#gdZ`YV@0?NpvPnH3vhxi^~m!*y{PL`s`Nml*lz;wnTkg#*S9JorY zrVP;Pdja32+v3#Ld{8a`6A=?TBO4KejH#`;vjsB|7aQmQ9kKkA!v1H1h>4M%h4sHm zm*^I71)Vhv`Y15yYkK&;Exy){4z^iN*6Ztk?_h4w*VhRCyI>T3!uIYaX4jLOA3v%$ zOJ(Oy-A7hec30)azm(OC(Ev=KnSQ_ep6R11WoW&Dn800J)G&ZxVR=wtVR1poirSMS z=}rY4!K7s45*yH0b8hr8jO2*&CMsm`PVX&Cftn#l+t)!f)_^N@yel`oX=#DjF)+4& zumZAQf%XMCXjuF}Pz5op5go@^1(Q(n?v}gU?80^)>Se>&(k&Z)z4-` z6unliei>1`f@8oYKY)_D&s+#Nzn&0K15=|fo=yGj9#GA-pFKEMHt-EDpew$rOFE!q zwPqr}ghJlL$WT~NAd7$UJd(u)obMB4J8+e?KY0xVAPE6XBBB(?uLl2nDYv04F*z`j zC9xs->V_a45bA;75Y&~9wK|PpaC3mI2 z-LOyU;HR-&R^jOiG4BJ`IwO$2<2C(sfU;<5X?ZWLf#OJk4h=2GK6(7xOF&N%$u8{f ztPs1m5ey*x-mGwm^l6-CFJSvNuumaCS~=SSyt{s?UhRT<$6**7m|cL={AepLk-x*g zsUgyT!u4l%0Au5zc_a5y0%|}LHzzj?f$AaY{#Q19KTJOdVd-RtXsoP7XFry2c15L> ztDw76qre6x#^#Xr^-iFz?rlKbKls0~EuPfTf9{j&I3PjYe`udwq<*MYuNWX^Kbr^| z{eEJKpnQ+$padTfr=B!9HD&Yx8b7&X-=Pyfgd+fPz+2D!Cx9lwxvA+(ME;?q??)W5 zv7!Fyb7DWarJBBmClAPX3+&^EZ3*P7trdodg+{&OXKB0@NZ(CpaJ&EcMo5cGTFb+4 zGO0>OhVEx~IM*n8$IHyh6j2F+NBgT=6DX>ZmiFhbmoB|>=E}yvTXF)RRIsMwVF#P+ zQnt?w(32V!od^r$>&r}@-!DnAHru>6U8=LnkS|3jn))Nr;F_LLkonFkP(18P|6Awu+9dnSC95;yzk zAs(S|bnkMzv=KU{|B=xAN%)pb2Y7PEz}nSteYRvJX7) z6@S~pfh_lE24m}BACa^Du|Z>3?IKrwB-gznf8h~*mVVRud$mu`3PTqY0OR%u7*g^h zdvBXrI8ZjpRuxk`*|OvFIcL17yUAbXQX#$@KnDk|rX&MJhi{;KVBt8j=y$;<5B=W2 z*>*(@YkBW#^!)o;k$|J0j>qtv%hio3b6Wf`%IDtJfy(BwPA-o*VV_~Zny8gY?!7Wp z9V9#!W+JgaO{0ZFms)Yq;X^?S_*kmca&OkXM{`sn{@g8IDec_tgZs(`_xbu7`#2Wq zOC05ZZRgq({7E@xr7MsavZ|E$BZq&yqzkFaaZ$i zUq`)yX9d$8o}KETsq1ge-KPY$#JL3(neX#f);|mFU%pX$cUN&-T2{cViWdXhzovpuH!Xh|t309gUfM zM!8KNrUJUln{wpDQ|dfyUz;W@Wll@$nALHfP114U{9Iyoe0@~wa@saI868tp?Hgq~ ziBbQVj=W}+(DfzLA`JH%+0TIeaf~woBo8kFE#t|b0V$f7@~0q*y?IjH_}RMj^4B^Z z=5sZOa%b7-5r$14EugCA*N=~>8vDtiYN!C;-bn%B@@7{Og<3zuA5NY$($mJ*xCZ2d z^GPI@7-TRUE0zRt7mmBC$}xJB1tF)Yi{SpzhG5{<%GWQ#e|m*#uoAYDk|X^`1ipjt zE?mPHK|%hh2HmC|!m1|>XIkXLgVt(CFpcY@Ra;j#NLP%xCLlb`b90I%x;bNlYT+y{Dz++GyiUCrFohh&#&7{C9*$XEvt^BI8&h6Vy!1<&$;UNo4kG zh;_G$LbEGga-*BK;-`Y8t%KCsmBKBNfs0VNsIbVDE=G%nK+L}0U1f6(#CX9mGN27B zmu&NoL1xbR8sLSjExr;4NtYIUW~7nKdxX^+bu;r>q=gd^{LZ~|i zeiF5KzqzwimI4EmwC3Pk9gKS*4#~JdBB-vXVDPbkDzQ+`k>^}@L4%9FnKyYDzmzN#d#P10iCqS zD*rE+C(d*juQNoV4ZB>}IUWjB24lPThiIl{0D$faq8Rd1OAk^ZHGxyqx?r{wpqxLj z-u_duFVZdcV*T$3D4XYt;sz;VTB3?~gM!c5BqB^)En6zYvomZ7eIz0+-iR4I00|96 zrjQ)e)A^R#Fg7^`8kpHcX~5T(vrKeIbP*3xIn$Q`Dk@wT$?3aliHLaSXa`kFWwei} z1||@S-D#!I(_T&rjR!-T69&;8td8-e^}CX&2H!XgQFDsuVc)=_>_x zL@Hq|Gv6iwW0{8O7#tP`axUB~cF^}`C5)P|hJ%Vy8faTW$p}?lwr$}Bm$({XAX&aM z$*`*qu;JVxL{v0AL(9^NuWZ#1j{ew90qh?IwS_Nr;%JIiSJ#t`Kj`%k-lBG0N}Dv-J(6@>9s-nqv4ggO7Rjl^{!@>3r>Y9Q#42TXF6 zpu#??Rt(Iho`f>++GkQ}or%Wm-v?&n*KJ$vL|@b;h)r%LLi?nM#1)z7ccx`FAQqK% zI8zDpR|=YVE2dHJhf}RbMB~o?&I}6+rVYT{-F~c&cUu*_>6t4m8XR2ZZ^YI%MnvG6 zQh>zdi&*<`gkrzw=8RtSY~k5^23VeU-%2H&(9ub#+I5iI-&VueVh7&gcaWzCMl^rL zDDb)}9V`m_)K7UxrqTp^HZr8?h>P+~7Rme~NZ)LFB@|}qh2yhx5C|XNSRG~a7`V$A z(AMB(7F;KIQ&Dh1f|%UPr;GwR7ojdbYi4*rjS2E<20=G5IlX1;9X^n^9KU ze_;GxOpl^kKAj9Ss*28!FmIht#++g+tatvcuHm_zs;Yuu`$#EIrINAMeKI9`I4^kE zog;BiT~mjTR;!e&STA2xcFhu>YBA?qYu{k&2X*GTvX#PkOFByG5<4qO`7Idd4Z{O| zZ;B>YLh*Ph{)}=RO8R633z!qz;7Frk>co*x7^!CyKE(1wfba>cU^GThPMOp9d?@im zk!I*;&2tAS#!T#lL11q`90B z`*F8%DYCxd63@!6H@HHp7Fe$M4c$u)&b1kz1C9p@+FN+X)q<^Ose-;H$v5tq!D!ppW53GO;lR z-OZEnjqS537u-@k0w8UUxA?w&_ouc>7C3Y!nW@`YdnW`_m35G(xCCO%T>?{3ziut1 z!Cn3Wc=^=>(~F&0Ec~X4p*DGO8b2_U%7kMTVSWo!P?J;ItpUxqA2B7!ZK_dP zXv4iQfB&?ZmwG%(49n>=m1cP&gvBYE$i*5m?cW}#X-9+2?SaN?F2yWO8u$wDUY#j?La`OoomaHy z;P+}D2Zj&60p_v;Z2jCTA`BTxsg$d14;*q#Z447=vP~dnLatBW2_+R_lw$OV{~{fxF*=!$b_&AXH7AOa@?IG zwsYV8W0aq&ohQ1#`Nb;a(b zr;UHI07&d<5~Qn>y|+&VRow8IUABK0gyIWHtgGB7-j^nKagbayCH>o`=EnFbWfW5y z&tADK-j~=_JkK&c9LZ@f21S$4 zwO@1(ar_*X1e6vLT68bsHB+&SdG))oZHY-SXI5>#YA#G}--Xz9@?uYAk>BygO+mwQ z11KbJm|9Ia%v0%YMN&?@Y;l$x$6d=FprE=s@3iG*GWe%5*C{i5Kj6WIy@d>@N-r*Y z=yD!OHj~q9NMME35dYci=t|PeUqw+=Jjb&DlrW0U?WhuD@dy(O8*xmZrMJtv2jm|~ zq*oK?KqAj6st&C&cV;yBr;+{$K2ZnqfZ!mK_G7#r_I`qzCU$@L8Nq0uI_$k#*6dir zAdh_rn}bZ(YA!=%9mH-a@mCa?b8^}C)5t2{^i#3R_>ACaf!hZ|Txc$p*wKS9hlq3Y zjF_1gMTNMDUc>r7by{62TdP(4TJ5ZE#3L;8_jcmJF9Rj5Q%Uav*RjEzmcN660jTtM zR?Fq~PH$NbRC}8er=#d#euq@UXjnNHb!G}0493eTe5yZx!AXRFOl|oi4 zYn{nWUUP{LRMX}&&{2ENExj=&qocAXcENCPfD>jL0D<~_ZbNn$0UL;+{I9Kl$~S~7 zdh;}=tX7{akwXU`3O~RyBuNX}|AZWi!)6=Wj3a3*i zGgm?Jyhx^mSudryxw73{Ox)9;;uZfzIt#k^$-*5QBgw0zV$J}Xl>m8yoZy4vuWiTo z%j{%m<~KE_0Itpy;2MoYM`5B<)mwSBo0K);%tF^UUMP|g!z+PHUq1JvO%Tl3J;i;v z%)X>6DpJamTrdow!f$(%GTkLt`s$AIW+TlEo)YK5!XdeCd0fokX;tw2%5iHr2>fBp{)EuwNjVz& zvCc4akfL5s;{feS3mq456v60_l4IQjYX|M$TX7l?BcFu@7{^__wlr*04cn#-S3P7t<;8M{`GnZd_pPuB%k|q5|J5h$s2zHcim{2wMsil?ympna zNvhR@NjrXtg4$*4OqTy0Ddc;}tNL;~wQLwpJsm52*rw&h5BwRq#H=G=l$X$yU-~pf zf_QZ8%l%Og_tiq^Pq|BVlkv#1+?lpUp0tT;+@6rAs zGwd}4;@A|)J7GmnVV~RGKk08=fI01*8|nFCh3cCl9CQMS-h zXxaKxm?Ts;9crxO0J6O1)aitH@J7-}KO!y@k)FM(W1#mI6G~le5LcxtTc#Wg+Rgy7 z=)+%?;zK)66@tpi%(?N4S##pQO&2r&Vq$L6GpPxN%7Pc#sczV8T2pzKSK7*H;^9y8 zAgk~a0nD;{JLX@gk>Rmz^)Mkd1N%<$!jfTQI1lFcpcT@`WIZz#g2`RrXAkf)!OCK7 zy--fB?14=>^ppB?(pG2s5tqhRXq^t_(u1Zol`V~yJ``>~j(JDo2p%yAFyO#Pu_868 zEV+&nInZY3OtHXo9WWA2eFbYnGP@>*heQsK+BWwer*zH`U<8%+bDx;&qeId%2yg+&*?_w$$D@eTNIfM{bp&f6! zchU=ECSW22TE3?5)xlGxz)4_;W(`Qrp4*tl20l-fOG!B^)D0+Gf8Ct&~=6XQbPNXgi2J-T(NE9 zT$u}&;?u~9$#g-6lI3p#Hsuj!FRXP3YMWuL^w?R2H5<*Xz$fH>@ zZsH`W&KYLrZ~A=^$dt05zZ$jP&irP;?#Poa#;MMu6+r2TWNy%mj@wALZZ5x4qG;2& zsn@TCf)-vJII@>>vpKJIt7a!#kFR+G0qt52+dr7FTjX^$Tc=HsvpmR^4 z7Uch-hd+3$_C9-~YdPJbv74bgpbT={H9gu`pv~44fthcZVMxu)v=t)3cDjOPqof0z z)}<9oySSUc0-c&L+%&@-%x8C-H{p!F3jx+AR3p`t$zMNRg{^0uRnJX2F^Z?9lE=ItwF|`jg=z1l9#=>i?y>Bel*{SS1%X}kcPBVmbrQpmsljN zt_aV7{{{29g*UB#s^`>f)y|VoiAlMmg3D4tm?qMbxn<0>={wOe?Qg;}wv$+(5HG9i zMQ~SoxDn*pVp(x*G7cOZj?C8nstE0WLR#&Bwx%`kwkChqm(E3;jFq-9_i)D$A>Y5u4zY8zcp>~!&2)R|@1BvN{T(}# zi^*X5CmwI@vA_5XL^>3PdXG;oJ;N*0Z5mQ|yTv%sW}*ima8btR#(5ET%69xOFi}F- zq_CGL-Kp8Df-s{1o{0l3J|J&?-thKM*}CAh@6tMD9Z_y5Aiyu>>uiW}Bdu(XFq76x zmz)0;YJ2#DO2ddfxWs zB?O4_Hnd}O0PDn5rws`aV65IfvP94?JOzI;QtI>E7=M5$3M=Z3Is{jpsd=p#h{{F>}D*s!CN?Okjqi24y!UpeHTnXYv zZ@1ViT<%6}Tk`#&CH{z$vcyK`kCxzx6%StTqec~@PvW^%MLfEf3Edq*42ap{YsShK zbS82H6XP~-HtNXMiGIB-O3(vh9 zW%3WTD>q4s$7UnC9;&GQlSRAyPXEE5jmr(Th-w*4?=?V)f5qs=Vxj;?mPGp}P$;WC ziqz}*+0>x;%4DiH-V%6JkMBisa}Qo04|$jD$`A9yC+u>M1DXt#U87BaNx; znlp$CH46|6ABZC6p4>-s2_8d>Lulf{t$pyuJv-N_i>qgcRNmu3BO3#sR*uG$@{WV? z2q)zCB#O*~R^zlYbn6K!&$3_wNlG5@&h4@QHJ9Nw+aUu<=P#V+Jg+spRLhqIVkUNw z^fipP=Kd)u$n@PrvgEjAzx*43e8(f2ZMM`Gd8ejR3FU{TifLhe&;_8QZ$1u!%acoX z^tK&J@KLDML~6yb8Yfv7gz$OCV7tSrt*G zlAgXpxlWF0cu+Llu@tW%qaLWcNR;NqJkCJcw^}EfV9W;QNt-5@ngwBA(|i&G_<@uf z>9zB)Ck~s6k9rT%dv5o!!948!FT3Ng%d`fwLl|c9L^a-I{U4f2nsSp^gR`k<%*&Y` z*_6&3|LSysVl1!Ctb#!*mFj~yAyyVZG8XNAeq}Fgu*nGRHo0Rq8#%`v0!QIOaIGok zZmCdav%ZG|+^Peit2JS~slPP+w_GHx#-9MZ^_5kY!LLA!sU^CmpMZvb5e>HA3S3@) zl*8%w8)TQkmW!@E6$$!F6gpjuhsI9lV`NIztd)pBGuZrh1W{o-b71U9buvW>0_F1^BVvy<5{tZB7Y* z>+9w_mid1Uv^*?0zGs%FN~oy-`X8Esj6;9f;>j&_jysyZpwx9|CeBjA8H=4C?D?Gb zGzVt!q00EyoLx&BF_!D0*oLAAi+d>de5tS_0`3ugl)PHW+bZ2eFO-XsMR`@t_@T z#EV`|t!t@)!huu_e{PpD2vUuc9o5?NptTW>J*jx1yFdb4Zm!FmWoZi42RH_`8EXsE*PJ*BLGPEpUd>%Ilib(5Rq+fN7=G}z z_(@a9zoxLoHwrBVV4BQHTCVn)JhU0g_$H%@Ohi9lcq^__eU&qP@!Zr7XIEhp*o`mU zZ1Zd4$w|l&)?aSonj2jlR6iF!pTZL_FY z$F(N2FVumj)xf;>=Iu>UlAw?n__z}Ku!Fn|vmlT7(=v+#5IVkKde~9G3YGRf>R293 zUy=104kgB-0Uw|+EU_cQL!mO&*!{k5V=Z60qKJ4G@;i{Je1KR5JrSAzlUoz&Wfyzl zbyS&E5H50&6D^;g>gyAqlZWrxCNgG1w`_vBJ#LsMB->Bx-Wm)yzcvO;=emPI*6IOX zqt5Zz=syJx5Y-IN?^X=rcAr+1zdt5JPMF@+)iueaM~@TTUezU&hzdh-i?$!=jRqK; zM9cx9>JaM^Fr#~~;GA&7t5@Xz&R58jp{Jo(9T&A>NrI{>dT-oLg-pG5(LePP^YERI z7TV-FXQL?1-m5d7iLiAv?!OUP=Aor;_PN_si%lZ{*t2MHs7Y^;O|rjt3Kr+FL4> zK?Af{uzud@+%SLOnpLm_I;Kw+D^#)`H-3v@XvTQ!nzX9ngbOmi$m!$zu(d?Rn0f4* zThibHG(jInRXHRE@5EpACFvq1n4AJH}tYfPI@^I#^Aq8Yl}a!qQ? z$vo0^X-WS-5x37VM)zQjAE*0l?Ps{6xIOj&l}O;WmHs59;Fb`SHRaM?34W+9@{^DC-zWzFNk)L}Q${5peX zSy20LZB~DMYYCh*2znlX1$YTL?MkHRS#=RoCWQ{SUk{o>=zmIk1I$@>zOgk)&A?O0VMV|LUW>m4*_1rL(w@3-w|baP?Ex zNIhpdS67Wg_V!oLX=mFIq?-Kz?)uhb43{=uROA4OEh}qn_br~a8*O(2@;wjHw-UqG zV}3x~RX;T^!*=oInE#4-p-&d%_^ccSz6na@ix5=OK1PK8Gkp2=p&6NI0XVUdeYGToqG>ZQoKdpZ zcRCQxbB@%l4fQ30xh>|@Xba48lACdS(J_(}0|>z%k^-{0oA~<{iJ;%8Tqt%`9E={3 zF7>g-lj%`Bu4k8lT>-&#Dxj+KJt?81l0t&}CvRWEM==JJkJEwu#%&^dw(YWk&3~uR z63+RZbr|#w+8WYjMv`j)ha5j?zQ--+(Pevc00{#|N})J?`|WZ%#_@3h;hQS1$dnCU?De|i z`m|2dE-p}WgB|Q18tq;fbf$WhC?jyKzh~v<9lYZCQfuZf_ql0@>*;gVt)K0e+8x~< zo|Rc}U0p33WWeuA(R;Xzq6@cvJcmtc3<$#L2fp~Ha2Vz10D$j@GBEK9l2+1TmEq=F zBIP1Y7y`4xP_Yp}0}mF2;wLS)TV+l|dZgKzvF=y&ev;4`PnP@~ln^Lg+j*4*a_j6E z`gwJ5+!Wz_=p$nf^)@k(lqXdkOSX?gvYl(!E<*0M-V%I9k%VW+NG(c_l|Pk-HMQH+ z!y@h2*sr|78;8b1j+x}ZlT@5y)ms5JMQlc*XW{DWxWDv(#ulcDprR?GnR%EQ;>0++ z_Tj>Z}w1=TOVr3Pu=X)OmywNJ!Z1o-40q*#W1XF6}tc;guwH`}d z9G{Pj#wS2XpTi?8^dKX0)V@+t6Vtx%$LgQ*Gwf^=GJ?{T;&wh#rLa_%&h6f&`NrO~ zLKp^El$%C?6X*;32FY4e>yX5Ry(C{S*sJ0d-~$ekvS+*%>8h!kAl|HXoqWBBAC%3= zS-O{Mnr|K+8lAYz6^b*i6fkh>KzZ)dCA(RcuA`2Dxr7R>(442>!Q)X!F4RJWK{5+= zo^B~#Og`+IG{Mb9=WhBK7TeazaurbbG2abF*QFv>5ja02! zss)?SH1%;|IiES)KBgg@~~Zp02FgTL2)xP5r3WsfM{uIsb<7wxo>cKP&v{NA+kM+(eaJ7qB2DSPuRlkB7`*5Mir)Ti z6(9;nbP8y*|F{n0o_sYl$n3X3wU;+Hi?q~O_qY+VYdLirUes@j zE-(FLlMx@-XO*Ux+>>=0C0iFXp%F}=fovKR`VADq`4=G;_Kw2974|ChDpY90@3@rb z-j(S;neXT)-?^iIu*PKnk_VmuAcem3B4~i>f$0Fr2}2@q!ed?N@EBJIWC$C{M!SQf zv_WINd8Cnn;teZ|LbF%`?5zB`f5SNdbGJqLGnioEvW9WqV)`kTu#O64Geh!`=oI#6 zXok`BPQ*pxEzUR{QVxQjV&bs<%G1P(N*zUfhj)zVjrR-my`&N9(UBMhB+sfl?hJd4 zfI`S&yt>={yFZKw{qV<5ChAH0)uSTgTL%7CgmN!kbeK9m%24#L1%}|+r!n0+-7BIW z{-quhpBfXV8x^M;6UR@C^%UYi5At55dMjnQS7aCy?;;^=`q#(_n}`Wr8l)`tA{i{G)2^)yCRR{B3{i+M#J}wAbw|u*mAVYO1~>f+f@m zTYw0uNo9VAt&t5HNgZziB}kPH2Zo_xVfzo;hna=rKfNvygNU82v#G7K6Vd-rf5aW_ zT5I(BY^)sAT9h6pi!8qGF|_sZ1BMUxjh+~ z{`;5dD~+w#gMV(%ogQJkB@**&N+o@|cl)uUc`!b-KNxfozYw+3o0F62#1ri7em=g< zLK4WdTT*p!iNN2D5(oC;9-cDuh3zhax79iFKYl*1|9ym2b@GlTQr=y&=fFG=O*=9y z8OB-0EpNYkA3p;|I_&hi!<87I?^VnPEdpq#I+I~!Y=dYVb=E|)pk)%gP>TusInlb; z>Tu?bbizHh8K5Ep!ASZQ!`gL!|2h6ytD9CC1;MvskOIv%ug@oI&Sbc;_3c(fLh&3| zc0e&%O&vB^S*Lm7*!jWow4(Jr2=07}*L=wtXR}T)(D4H7YC0@4U^?x zF>s|xP9usMz46Gae_YYI{4=NPU^)81{l4V8V%8rA!4-r1ML-XoAKwj^^QThk*1mGM zADth!;*J(DSupxzy{D24ra>6vqa_zl`(0=((qsTr6hNjt8FXi{8;)Ts8-s^E9(>E{ zuV(3bM)s3IG*xZmk{x-dKfn>&z(liH5J~h09o+C9E`!LN`KpR}Fz4W1=F>Rk6I3<& zEv| zY8C)C1f2cn(tgj@JT(SX{9Rht;yAs?j0&gRWWDM8%(W=NSC5KH!;#!bsP}M|&&RvjgC2D`iHtUB(SpGH{k;_Z!q-r2t4ZKH%b11?#6`MmV&5ce$npn?)Ek&nU)ckdQrzY+TjQhv*Q{8T7+)o4zmR)011wEZ;ne-WX_BK6GP$LrzMN$}l zIhATpEz)^UQWyX7R%Qup=AVZ%QL`cbM^6b^AR37qEbbt_(XgQC@w%#z*Z=@Um+9Jf zz8Qsw1y_g|l@#uRONO>0L<0_;78fM=H|}lpuY?FQ5+lu;&;{?O(uRnD9B( zB<=kR>d1GzEtjEyIG)0yRe?n5G4SoCPBiNSVgw9`%@BrT8UE~*5-CZ)j~zSg4)x~+ zjYR}a$Iv|~bdh3;snctHKnu`IgZJp1`6ss)X3e4HKr61~dm96iz)T$-w8GROuCGfl zeq+JD-bi`@rl>hPv86e5x^B$K75Ftvw9ymmJDXMtNql`&K!g~cvIEn;vx!aEcryAI zsxp}^1w2la7A1bB%6xX%vyY^gE7*2@tW(@dX)DU_bNB*BO0GO6M+!h8DTqBHk_POT zul@3)Njb{C>i=QuouUJY)~?;CW1Ah@wr$(C&5E6lopjVm$F^UKMtPweXAAaP%e(d~c8D)1E=i;|pb?Uf(vL#w|*gZQGc zp~B%MaU#f%MA#D5IVZC-hS2@yjs!ARnm0JF`q3%q+Sdr%$PaiQa+UNe|H8H(bd+;9 z_4n3xA%{oWm?03AJB8)Zh!{pjSNtf7$byCJoH#PwxOP5QUF$eLD}u0?lxo(wT}0oO%OFjR$9G`!<3WD|r9{{>OQQL5 z9nq2|uh+fOLMhfQXpsJ#9Rq%qC|vGp{F2E#>n1H7NnF&O59UW7MQkyjp%@<&<4dxBr>umPAo^$^}NP$HFEkHSntv|3t+B^}$(l2|^(y!D!Y>5ht%!ZPXB^ zg7dAs2oF~LmBxUFlQ`3(23hAsp<2;?{Zj*sV?i@R5eYKC@0U$i1~rf@mkmY}YkE}J zwn$-vvV2Sds)rojD15%^tS<|_U-mk?K8)E(($H5+a!Hc(((CSgk-J?$1mTRy;(xd< zR>T@fgFI3gHF4M=I77hws!7QN+I9Yydd?|aHoQ~ka|VFsWoCusV|`L z6qc0GA~3L^`u(Ys7G2$t1mlHBj9C0RpXDMBD(4X>LhC9-%HX(*p|;O#Ustpa4Xzsq zT}VcWvLi|oI=qEb-P=;<(K@IVq$OyA!S0k-BB2Y)R!(5MzyK5m+%XC4>?g<_udA;l z)K0nb!L5ioBb#{>*DNxku!*9VpoY)7;CWi;L;fyxiSfiW?5z|&QfSl0aCBELZ`)yWF5#{U(w)8Z ztcSv)Uf-jl=mb0=d5fSV^7<_gm!gyi9anHH9wMN_ka;3qMU<7$E<-&P9K2*IVC{Nn zY$M7}kzTC9*hujeYbwduR^w1{S7mrBB6cv^(D>PMamTTxlAH*QZ-NcF~Wms6mg4rWjRAEVxKZ^E#M=aJDiAxi-|{lW!gqsoQ90YZ$J( zR(In^*8yKyB{e6z?cN9`)8OufM0eO!f@6t~Nn^GCnYpzV+*v`r;~IdIHgS8(nUi;qBL_wMUhxNkTB3%WZ3=780oZfo? zj**@=2G00@qrY57g(A89u#~VAEQYg{8gxG1vg-OA;mc~-5iB8pM zj_9(|avG0g6;`zVod&V>R#a%NXLS53PhRB)9PlJF#0k_&B(f~zyRP$_IwJGb^d`sx zxYQN|^$J+v=Ze7FH@PfpxBo&}VV3`isDE@F*mTupa3=KsKa`b?{XY+{ZW)|9{j3Yz z2W(TX#iAR04;J>`3gY6mNB`&1$$y9HIrul!|L8wtHn#ujKlc9#wyF^6r;imfLG%lC0`H89Yq7S~DeEl@yugpZwZ=XAtob^g%%pt+rz-fyGT zW~R+J;*Rf#$RCF{&2(&<+BB<=aqLE4~^Xw%bl z;{xDgzNGvB0iK`X`GOd0&nds!HiVq9ym)F=G={nfxyMA@VbdrLjVxj2>y||l(jZgQ zc+$Q3vW!5d+{`!W*b7faQR=$eDB;BIFv4S@=Y{uy?h-vqtIhw{jR3%kZ_>;vWhA%Cd zWCfxtQho>ZM^v$6cPj6nxa`_vfJ~hX88aQ74Kq}0y;zb_tVx=<7-Iy*Bn(|_iYnVIGPJ^y#Ang0p#|Cw@T=Kq!e z{E9|11LyN(id-wPkQuP~sN(m4C!10Nr@mr@stkPvS5^%to=b zHgdPnj=GpUdjBc*kY@733jtn(le)V;l!e!bRv4!~HJ@)v10>gMCgKXRS#5Fw498%7 zsJwdJ-&O1KW{HU3sge3CUoN%6zwPlrLGHDN?{_Owv;F0WhxkTX72(zn=fmFBwxZZ$ zrd}4Uu*=vRpi8);ih_We*!m}9c)|7)!OS3g=y>o4H%jb`a1M^c3C_BHi_V+uzui`7 zAk6b6gTBOtKc5}0Q0~Du&_xxwZw9jgBkpTBgk(X>l*mnsc!yK)?F5&U0{h2}C7{b4`%ZUr0-Hoz z0Ir^uY9(}lMya0(HeN}Z6=Sb{A>v2f z2QG&WP!u|zL8j)Be!%CPMJz(J0IyMvik(X2evz?^HVR+h)~}nt(k4nLn;*(5^6hVp z3l1S;ggh#1^K8u!{wmZ@OIabJrekkX;uKS26dhEH3w&bGhu?=dI4HQQxCwkoi8E2Y z!Tn?6!_>Va?Y^+@vZvsezXltmucx-j5+;p;fWntRZt4Y;IU_Y;I2wc#kSZ!McB(S!)Jo$f<=7+bsUhE?;W&&Hulc|C8$Z~OQ-Jz6 z<5xq`K+}khnCZnJB1r*JyR$u{ECB)DLL<=?bxwYxR3E~47@Lfi{L*n-3 zFkuUM*1UPB6uk*K>o}N3)#={Dcc*^+04X?A-NNE@(1{eTW$8!ql|K@yJZq{tBYGBd zJ>_Ft&o*@R+`}r2XcSXfnb@z`2y$eCQ9+N+3UqrXCH9@fL~d@V|t%j&xOi|7-zGFJUoL;WbF7%mc%S1 z>5$WYUzTYqKhe8R>Pj=9kME(d5KOM75wCvvJldMcVYaI~2a()&^h@L{Sm%40851!o zodCmk5LL08Mr-5&#E9}RZ5rAl9JtG!` z0HRN+HRF?Rc6h!KO*%E{$CMnK-e+~sU2ZuPnU2s;O<-w3HGzmhT@f652$Ufnj&y^F zRNpGlXeEj5qSJF*IeX99iyjn8^p(iXK~>Wn6<1Is;Y3xeYtA0qX6H8m*6@zO5Tn$B zEW(hf=&$0G3wXP_Qnf-ne?}nXGOvq9aRA z?)0ns3r*prg=^?n2op*YVLs7+V)k)|=bKb{sIy48U~P-+f{rBL$HfVl9%~E(`k=a2 z*&ntgi7I?HOyE&njau!rFhVp(B(LYT3tU^YF?6x6d(|d|t3RR(9|pvab~uqbE-k`N z`SC9+^0?9`8DS>?p_iHIlf?64lllswcK?arU<&k(omS8l#GAVZ(dHw!74~z@8E2w0 zpEc`^4Dhrb0n4Uv7XRMo=Hbi{BHl1UPx0aYm5DT7ta(rwzd4kWnIlAQ42Yv|`!aY0 zk-r!HaVm>)bpqTGF1R0t;l989V`ol)QUs8l(kY5B2OrV_RO=&e_0sHAPO|V{U>fUO zdWe|DTdYCK*O3=%gM)l`etvo(u@MAtKfv1{{K3G^2GJy1vg0EVr0mpm@mV41o5Ax{ zY=bt6&6Mi~UV{`uiv9U}<#}-6<-cV(N#3}ve`{M(1pV^)2!sXMAT58KHPRVS9tAOW z;Yh{TB$7k{N_mcG2Cg=y)@MK=3UCR<$K1{F*NL#{g|@Z>6ehkwsh2DSGkaJ|1cO!w z`Bd4Ba@RXk)CIKfdwW!vjg8`xkQ3tiDJa6sjBcxLBx4v(?O!Re1zniqq(SiXt2%d# z2;k_Q{OgJKhGnNuoye%g=27cacwhw4=(SpVzw<9ORzw(;184Cojufe&0%T_E?O_8o zv)F3D7Nw*`-1V3(h}97sk*@F!6~T#7n5iAkn;nA5Y?-G7F;5&)LLce)vM^aqO`V`* zS)S=^K8g%mg)xHM6JtwUD_Z83S8Ou-|Kcqoby%BgRQmV`ojtoz5UOU{Le zj1bOKra9teLN)19HN&5Ecm?H3+MWhVPn*fdxfZ;hrZht(_@a`! zmVYze#Coe|#h}Q7HCmO&NxmTF{w@sdx1pJQkVquH$Iazb=xG%K2%M=vP#;CFW+a02 z7mY9!jZEkEBJj`yTy_(GS|oF*Jz#F-Iv=;giYwoiac1#qkO@hfOE(e# zdXH(S5zem#hwmKu>>m?|Y~L%j3mmp~&+MbN!FLZYiNu17AbIlSN5Q}o=~D7y7pVr@ z{HY$+46mp3Jj$+B>n~4>yU<0cvouyUx6p*+<9U*cA<3u6b z%pR)LG)&-pv^<*vH3W-%f>Um+%mE|89MB0_t18&$JMJjW(s0IgPu6Mv*pCa7P9Fva z{uvv%qe6cLTiBVFwu#7b1?kd{-kWlRl9*OQU~1Xxrk`%FAP?j=I$*~407U0;{!Ltd}6hVx==pytIQ4`UM-O97y+y;&9mWg5dI40f z(p%H=z1xiiiM>y%YiOkU2=Cs&*A{a{_IoJ;;oEuP?_i>;vjGo+4UFt+EU=xJ*<-9N z%%08|y_v=j93eZyLiq|BT3+hwzIErX!*9IysvfwxR0>#MWj8;z9bu|s3zq77mJt28 z6r~-w_h>#>La$gAnMgb1H3To1CO5GJbk9FKAiiQod_{+n!k_5l~O@R02wF*+bvJD_3K-V+8iPuJLnI;_kS8^C79rK&b@a5XogA|MuwVAp4q6&IKpk z`Ij)t9iAgw=>+3@iIKlFDrwj^9ISx%(cnQi8uf$<%rK!dRnw$029)qDL32-Ku9b?B1S|y4gx^E@M1bnQ#gev~z-zDujyazeTEu$FrB4OzR~MDp+@-_T2IyAmx{?mpV3sM*&x$mGq}# z|K2ibZcdnX2tI*VDxn~laAX}3^NeiCd95iGPk#lGjj$t`z;5LJ<| zQS$ob-I*Z;+=*WQwbWrdxomS1!a8!kmaN@`&~Fh}Z7lw#AXD~S;1M@e09hy>vG`rj zw{WPV`gdPhOK$@uekuFo+*Z3qVleiv_!%r3=MkXz32LVUlrMAvr+D;GYet3=)fIv* z)vQe+(xMq^d48~`t-ub}GknAF7~@f>#zJM1+I6>h+RKlc;Y24k$31Jrb(6NgZ>+hQ z5jU$9bN?8O6~9@L|4Q+|q1M=Pg+uX8ZpaP@oR0d!r`B_KQxt02lEO+u#$vXx?FH2c z!vlWLO=FqZ{Cx^I_G+g8(H|x5{&zeudks@J>cW04*Vqvwk~aATVf^rBmc82Tz{dRI z#G9ADD{#G}Kx%H9J7jEy3bhv2_uRpT2G-~F6VfG=V!;S}c}nc8)~tXZUTq74uJ1ch zJ8^vnIMcIq$2^@tQEs#6fzTa}6T@e5dl+!jkg&KD)AXbRU8&xD&kiHao_Q@jbWK8= zYc71PjVb4|!G(v6mYT(hn^tN~WRODca#@?(l}U;mYN5d$@hD(?;|=hWG8b>)}%WhjCZVYk+%mR0j}a zdn$i|v!$FeAL91A?&`Hx#yvQcb4Sd~zL3Z>wK$OzP<8jAF)tV2xH{HydkMY*wy5=&yef;)S?rU3avHkn))S&9TikMVItpJS$6gM*({4(b>;{>M-l*FY! zOD+~fLITrALc&6eg+*P~5^v#a)Oc)Bo*);X3-Z|fGKu8M!sP)*#Sn4@BVB}e0~=!y z0;9h54o*)E_DzjK8(Ekgz9ONVj3OYjyEUqd^6k#d&Q5G>z@ACX13L?u?m5|emJv}^2zG1Itz6-N8I)eqQ; zRCXh|#gF~zP~Ai@J2ibSI665$J$Mn%CZ~6Svv@&ApeI)>_Vvdv(&#HOGn)qhU&Y43 z;a=qiEkOiP^)!VG7erKgsO9`n9lMWsCWRto^v&n*y&y$UC6r}dh$qxyq!iUu4Qwci zDT`m}!T5?X%FFX zBR7n?)V!=jf#)?&f@k-63Ho0@LC1TrLSe6ax(|a0lWk%1-z{g|vDdKU1iLdn1>@iH zD89Z*-jNu;YC=8%QdG~nx))W&7p%Q6Nk=PN>w_E415+3M9KmKGMBup&&f_b+-1v3n z3>Ms8?z2W=eC^s4EA(R0{!>>%meN_)Qx#2I*3vYlXZVP*ZJjX2!qnQb9NMk^{lErv z_Fs+hlW=Rq14kFoBUB({efd3pZ|eQ|B*n~Ynm*K%pjREKES_((!P4*sV40{oj)TmPxhY~&yj%OmmVV8z`p&Sga=X^I3!=V z1pw-f_$?h6j(4*E{3hs9_W>0^M>f!7Cs+*vxhuFW*h zJ_yb`KV!W|J{q<$`G@|wSF8qzR9AqJ>HEF;7s7r?wrR{CC0}CK%=Ylp4!r=5AKUnm z;WerD3IO!QLu`JkzaZH@0ewhM-+}(GOg&R9$&vWCx0#M3)5?FyIX~@;toCf&0fuSN zIPY$qCI3sWQj~tzq78zBY>JH~sp7&r9k=(r+fe9Ku?K!ur>z?WD(g}xZ*$$)TMehE z>!tJ7CQzD2df~Ei!Q)VW-?5oo3@9M7c^JX)1(6s)`+X25R`+}~YqVr2ZXbfKar}8o#2lFph0#G*g zvoPNI$;&M^o9SoX0ylhw${A^N*~Ii^NZ0#=%43^ing&%)MCu=y9H7tiXD4KB>DR*b z0NZk>rnU1S&yF95q}Sx`{L1#THjX>KiJ`dNNR7FhAI@jJzSXaPJ)wqiesG)(AKZet z!1nuC)fm;Qz%+!~Bo(N9(D}*sjA){QrFzLLp=A*Y3VP<{l({SWj*J+&vWj2EuLX1; zh;E!s-kJm6p=PB_IVlMrDQ1xM67^&?Kp^*n?!Rt>a^9oV=7H zR-v<|G3{H6V;<+bo$(ydwO65a<7Nzp&L>CxfkF8+%LCcJx79edZtJa|$2o&J2g=G^ zLe0=~uI@Qs*?a{*qIRCaGC_HBEY~)BMXxN__0mP=An5Hk*!aVR2Zm2m`FpsR(N83@ z@s|6ZwI}s0wG9kiMB?suWjM7(8C=!GPx25kvt>R{P1`cIG^&@9)%uRx6`Byo2W!xF zpn|0hOypn{ezNf!bD6Vh`O~@>q zD2nLHbK3Rs^!zg!YfnJ|+%9qPP6l5-`SbLZN!Un@`~mFy2uqi4`BD)>S{tD=FH zQ|PhwhvS8zj0W||uFn;P1J1w3{%t(+2#cT8 z#NDiptLzxEt>4=PJEWDJtn@0BhmbO{kF;J@q=ELC?0Yon{O+h+3J|VLE2uhA?9E!K zr+6S|#%$c>(T-8eT$Vez!JoOMl5|5l6B0R8H9yvF?5;B7I)|;EdFbiQe`lpj#XR*R zHXm6kfl)$xlbGK@rB46tBof7BAj$YzPyOa!fv*5r8t+kEf%BH2~PFM^%N1il_uDA$#C7sUcFwQHb)Y!`tFJ= zE0p+_1$ie_E%r1a;FL#_^RAnP?@b^HE<-C*-?0438v27Y2*~5qP12Kw!*lj0azFO` z#SolaOuC&lT1Pf_GU~JLv1ZFkn>E;)yf;m#Pnz#J!Y!&jcoob4gh{rGan7(FEGv)= z6*K56Tq{bU;%u_W)Cf{h&A-(pp!u3NeN{D!ZO(Ljvuq;Rvw8?HJ~G1;|7J}M->4yM z#fXv*zNP&`3eY954cnoM*Vex=h+hO%<3vOCkgOkm2yG`~J)SRTef6?b6j|Ot;6M;e zby3`|mM#@bg4A%C)pGxa=)0)NZuKXan@x~SC$y-@1sr>TmJZ<veB{r z(C;?$&Fg{UDa|gbU`QR6A2PDjsw4i>qo(;B#hJ*OOu5OfNV2=mZ#KiSwQ;i;5jBBX z3wM0_91u6~8}fbPW;@0?kFF3cmqVs|M;Q~OeA()`J-)d+@LsF0B3PkPT}RVD`Ea;m zmB{39;ls8%vL@_jeD=4bMdY$d6KGS9r=Quc@omfo)4`ew_Ej7|iSAE(U*Sa?5kID! zs5U;^|JQX1bGfN^vE)n?AcxRZZCH#7_yjJnWV|35U~K z^(EU*p6&s@6WO055+`9co>_%!&`5Un#J|MQI%_4y4I#lj+VlFEbYEUNp5VsSBL8FKb}G3TM01EV(&$`a4K<)pWg(?R6{SOW`$KLuLB-OLgFJ%PBSsYrx_o zz^-~ER5b={Gq}p6`LA=&1>}DdPk1W=GC(|QV!-T+N_DIj@!nqi;-rm8R3`&rL)^~3 zc&znZ=^aA8Ex*=O8DjP$h))2q+w=(M=dKr=($3snN6~hZdrvW2SIuD0{=z9?HL;K1 z#0U9iiv8fJ;2cj`6jM5drp8?naXqYiff?Kq>au_jDSNO@?@cGXz>243>M0LFHDD<~ zK@gojG86jPvCZZ?SFMd%WzzDYRrVy_sb$~0PAqN5sUu(I+xN%vCb z=hyd$3%3|T7xH(#f4?Btwz1xfwb|x5lK{#Jp}*vlVDT4wsE5##JSGmvt^G_BkM(bl z?#G$Ym0dMf_V4)1Es>?|cKGB{6~OZO^Y5Am=N+P{4N;gW)#V^tT4*sd2%FZEEdtCv zaq~;s6jp7JKN}&-FFCK(>-q1fI=vPH66;9c>@K5fpPBs$f~*jZQMUVxAb&1XJxlEK zo4?a+Ed4yofiFMnV7Z5{vmzJ~Mxc1kTS&g?9V~=lLyo^}yB4R}n{&kC$pwOC|A0m$ z9?XL^gD^uy3=P(B=2ZH)CJ*RJ=_eO*%Rh%R>fv8+gwb!I8K{er6B-o$Q`PFdPh0QA zQR>opapGeImmD)kwaMk#r~<$-VmsS?PuT{~GxI_Y82l@YnOr(Xt^RQ*T6V%*-Wx-s z@qhmHrlNFx>bgb$6X!7@J0hZm%;)Eda%2`GMUDJQ>0b6GdEaj}uLK1kh4uH*%W@b3 z*~i$A?c+M_fSbC=?G(rA8<_%84JmF%s#c>L#U}(stzeWm>+l3#2O7R#LrlaA$s4xCFSh^ zfye5`pei!N3KNRfys`*6Wwo}SHKI6pyh_4gP=p~)t!z4>oAd}(GHmgVvz?&2U0}u0 zC)s4K;XAn!oB}Tl-2k8?5E{1;!iN1|f6CP_=1dH${=PoD@9$PjO&I>pKwH1?lTAWZ zrgjnrGvsIN*9nU7Uj~+@)jZMftHl~whYh8qO)+?Xq%zpw*<#72knFMifrA_KUwr=lO~BViuRdJNDMT-xn>yMNi~sxq^dJQ*6Qx$TKg=NM5QHG*_ zi+t%*^vH8t%-?F%Xz?)jblM7@MK@yxs$t^tScwfS%wu!wLPI1t9kvtJ@r!hBNOCOH9x3~Ti(;3#L47`R#!$4B@of+lDiATxyS?9HV+7|> zsc>U8zEO71Jn?usA&6e^CQE&ZJ|J?I;rwxWi~(-QPfV95tl0Shij&-nz-I#&BaRrW0>O+4+6-_84|x&TM1d zmycY%YygM{Ru0YklI_o}{folBeqV@uLWvjs@t4^(8hpaqs=peA(+RB2x_&b*(;dNE zpmig(??i4u+XlU)(^9iZ2k*@vi=!h)jXC>NQgPwn8Xa0vKC9xG9*Qw}SRJaT-#QwInzrfsm9OBkt@z3nY*y*F2O#&e8 zXjn>R57{30adSkits&lf>M2zjN^~TMe?a38wX7e(Kn`aMl!N z;CEX>yx-$nvaqK5A%KXUF$w4;XtO$53x}z(6p9V5CG|Grb2uj}C@f+DLJgSbeKhc@ zWyl=93R8ksRtb$Boes|o(iINvBNV?v)wLN-?ZVLbkaDei@(~1E|IT1w&{Cx$U>h{Z ze0{`8+b1LL=y%R5C%6oD(~^u#NoX^*VhG1Fq(N@IGW^&c&~2U5xfQ%oC#b5O1zV}( znb{x$K9(fZ#&tNtAjR)*`rs1~01h0qq<)ao_Ds3|MG4URLZdu{z=bg4QvAlPQ2HoB zF2i{3i)i+vg7mxtr{b2t^~L-Cmxb*)6<8zQm?fFNxgwucl`83yJ3y)>g6*qWZqj6-D-!(aGX&qX_ue$Q#TkQspZPLj3V z%~8CVDskE6xH6V%dp6}}=8be*f7?&~B1p^bwGzA^W^6zM0#kaj7Bpd(*W=Z&0Y; zKBS&~$tF6_^Cx3-Jd`Yruikw^G$RV027xwVR>C5gK>qJs0gtw-B42?0l;D&3^dm{o zZgumA*miiNiw`sHi{6X3gj+MIZaM?{eSqZ6dTjLm;6vEMhS!iHv$cB?mW&R~EZY6HiQ{lXJ$XAW^nScya$MJV0hd@x@_!Vf(V0X*?@tce?`zUgqmBEj;51}ydMD_L^@rU-W%ricV zEU9=;%gq{5D1DL?(v;U^uuySCYv?K8CI{c8#@flxl4Tfh`FKDzocducWIc!YrnAK@ zs_0hg8_0}pRJA>OhSla<`5uibL9iw=1aREu$rWF^JBzce{r%UA=81f-oa;-zEFPGW%K3H%eY+7_ zaqV-%Jj|@BpQC_OW5fs7p%5cq`I10P(q^d0=@ODCA(G^f&|-N+LBpsnPt#4PyqLSw z=m^e%U#ZAA`>f<;i6UVPIf5KkoY+n+siaa|YBV43rd%5&2HSgA8iJ`_B-Bex?^PdSMCbR8w8EG_c=w!{Hp|NGYR5Zoc{qAOYwW@s_IT&jnwxl>q7fgQe zt>!@A{di{EYa%7H&nf)%t_1zp$Wo*&yfNoA(PPOE3jM=AUx$Gn6}--c9_OsguGNK= zNj@KVR(aB4%8TR!&;>5G^QcKyKQS|jECq)v2+)SO7?fUZczVH0ihbPBMA7t0Dsvq_ zjJ7!qP#=E$Kw*nYwR)y*jcMHkRjygKx+*Mj^>;=N_jw!o=Pen$`82zk@5svTz|sCl z_N%PzS7cWlEWnU1f)kDUTbLBNqbR*5t(^;)^WrA<$l?WY^m|C#IwOq%ns;m%L| zDwuuL?7Mr58T9R4Clhv6GTX=^?@i218hdx8L1FEyeY zTl=Ev^aS9T?9!{9p04eW265c#94DV7tk8^jYx=w?mr7iGQaSggNTNOk>YRa64Ps8w zG47yi?kTBC*;6f4cP!Mk%4Y?b3PA^SpUc;EVsgQ34IuTBXnWF^_tNbVv zd6hMR4JMnd@!nkobjzj9u)GmSXVuk~FJ1&sezD3PW{9RD4yt^$xTFyQh$uq*(8QBh zjI(Ab|2!;tODVVR5s_5Udh{Bl6`de9mc}y>&~3_fXKY7lShOdc>?UpWg}EY0tt9ZV zwet`P5LowzG{wc%wx-R+`jWc^8%gvX`NJ z>x^5-k*@2Bd280;yt4Kefu*}4Eyx#d6)@`QC2L9&bHT~WOJXUlxV-eoaikdJoi!UA z&PZ~os_yBeEU;7QyeT5)ZkfD_)IABt<{gZxQwo{#Q`<-x1QMaxQ^Zl&MS$eUIHIrLE2;j$9=oa_efMvohCZ-&h_nzOEwE@#~V1n`DfR zZv%5w4nVZ}#9X|A+1erhQ`R`}|MKP+@3)3C6mzfHOse`#ft7;1H$WI@w4 zCd2(|DW6HoRxwtvO}At^8m!P-l=~kFFH3Eu8xMY{p>xCl;blbFS`&rvJf_z zj7f5sdIAEzNxhz-1^Q20i2k($mQD!W5{C@ zwwA_-C@#^0IhY+(%J|PVSY-!VCSb-g(w}Q>lz?yJ-r7W!2>iBn!(>J|9e<&*vze$B zpfg{qcEa>%m%EEp1h@?A)Y+_Rz3@?R5~9dp7Zek!I=6hi+qn4{oXHB-i`~35eltd8 z_7kT@6Jx*X1P9A8QRK(5Q+lj}j`ZD~bRFt8)p21d+dX3#sJOcL%p6m3AbF)L@o(-8 zgaPQdW^?4|d%0J=`{><>QKH7+cs@<01pu;fGZ^!59BIV$=?X*BcK5sr7}tI;en(6J zzq&y8dpCzZDYPT}N%V28&RSW?-KM`^PMG@^{NAO`2Fo=Y`|Wyc$f7yql?6 zkXbeVIDOw3%~%0%P<8N6Wb>dj(uP8+!awXUL-U`Um7MnJYuTzBlj)F$!D~meV%ZJ? zHxHk^zd@l^VIHZL*vH9#FioB7M=O-fi~6ZG9GUM?X)AD2xH^o1Ryq=X6}hE6t^+`2 ziEQ4RRmEya^vWEBD`eQ1v<8ljPFps4a?L`5GK4l3dG#7)OM*29>Z3=KpPD|buEka*_HVR+6$kHv>dQKI&llB)nU*^Z_sW9sldBQ}a-j%P+$u;@(Znia##~6yoU8s@ zpN%Kb3#S{74z@Ew#KMR%?-mzFf5O)M2{;bUM|y;k%}t1Fw1h73h|1*d7!E^<>vsqH zsMgEia8Dw9*8XS^7%8oLkNTKl-&f^4^|uK%E1Vl6`4;XdGvZ9BoTZbMup^g=5B9h; zJ#Xm!{i*1S2b0l+re8lf)dKk05)0lQk5+>0l}14b_rn*exmj=A6h_II{?@!8ba=hC zftIi(IkWbJrP>c28DTSud5Ld0=;boqI-b^~0jD+4p-gm2=*_e1`$79HH6|zu_5rcw z0<;=Rgz@8Or@BFak*u0V?0BcP&BtTl7rG}RR|#%rQ!-VOkr#f7>IhI8!@=l8+aVU@ zYUr|w=B6f)!X5bSR~Glje%$Fd1k)b5Y4Vm$tpw5Z9O<}la|?P;a`Hio{D0PlLgp?3 z*E|?9lEu$3o;`-4O_*vhrBv@MjBGn+vZ3pqoQg?h=_-AVd6Xfw37b=gQsRJM!`+#z z;a{qB3Pq>ibyj)iA~b<*{`V|%hB(JR4wP{F*&iQoj@v>mbtrU-3yjc%A#^APGM=GE zJl~26|6XKt2IWL2y0QgrxS{A{BUfK{fK{st8e4sIoT~@>9HsQ3|5UMGF)j=nhy6*% zX#nm@-aTn#g6y8@TCk@qUoL z>V)1ILtH9O7||D`;6;=HwPn7_4&jzwLkt&2Suy+^~NQJn;QEZRZ|WZm`2AbUILD4zxTs*AV!{HlxRKa zX^s%-XwEnOx(nk7L-0xYY`Q-Q+$+rwyorM_w>Fb{HBahWsJ+Pk_Sy@WNuEHF5wzbK zuQ%!a+3lJSbQv1{nPWC#y@x~K=leUzmo@l{g>OgysZ6)_l3+{*?bNbyVhO|Vc^Zo7~7)>FGaYd06t?^98PoO-RdnfL!JssJp+R5 z*EIbMUcHjB={iLr0W6s5DPs0unI6*c^99cyUbApPd=@kL(Jfo;L1FOhnbAyAg>Foj zDjZtQ-p)>af6vv&gA>vhi?#Cg?>ogRjn2fjR$m91^=>b9jh&k5)i2kEA50N-nxt^2 z$&F_+0L>^}Q$K8bvx`KOiVhepo3CTJ*=hPK!u~cE{Mg%U(3!plS#}s-DOcljx2VN= zsk4M86=pf4flK@$`0!s&m!0>*c>hmTXB8C%)b(#-2I=nZmKeGvhb{>z=^j!_YUoh9 zhDKT%>2B%n?iT4TKi>7Nf4q0kzBo5$opo;Z-p?<{9WhBKvjZ%+q53*)gh^S|6M{vmR+3p?5dpQTZC6V~#yNQT5?$lK zSV=N6Bo8bq=f9Yn#E%VSqBW9BK-4oqy&UmfBG4k~JpYAt+J10--29SRC?9{~QFh$^ z8T(w~_%1yKm94{IVbu^h`=>fKeO#eb1@!8^!*fbPfCP<3^OHaqgAqM%IQn~8&5t7Z zoRY>C8T<=$%5_lTdnFov$hn{DB+m1ItT!>~IwG7JEu0RmeHao1mnd6&`K3@waE-YW zQ5@rM25sJcu3*)#m=)DuKk|W2%t;PzTIMZWhOc{qr!0kTi~U}Z;0KTJ432K0tuQ(m z*H*NqM9W{*#7`2a)k?+9leyA=kVNDdL|&6M`4eq(#ND7*9=^DS;?I_FF?N25=WkB) zHRl%pkDh(jA#sT)PZ0Epm8hcEA0oa)OzMXjS1Bsc1&+%?sKi;H(IP_ zqdWB!f@IS7bAkn3KQ59BoGJniRo>4&FrgIHvtk*%fuHbrJbAmESv)aRRp0sg`@prazWLaJWxn zK#q5f8yDFr?S9#_Q#(~_XS_{>8hid)!AnCfv`|dSj#W;G)^f6_`1+{D6W_$-STNhn z8hLkOE04e2VnX)1TLI76nDYH^OD0rHmmYTXc{SEjrqTH@kPMuvh7x-LyM9V}gPdG* zYD?=k`G1kL3%IguqGruZ2F?{`0|90kZUqUo+5)A?t-S?I<{f7^=8)rg zHD1M$rnBKGV(dAM$=Y+zS3@qWkCTEEUaqJSBo5FgRG4^Aaklf&iBjTaZqH1-Cqu^8 z#M2wPTc4^;Q^>t}*&}u?LM{)cHtIUx24wM%yv;nvMwo|A?Gn4Z0tF88rc;q@zL)x< z4R}-8VBH}V9bNxeNtC4kJ!ozKg50S)fW?cQ$s86=eo`v}<$etDwBJuxM)jsPgsU}2 zmvmlHD>h>x`8DwiglIU7I@)$M8E^R|>T}HBW9x>O=|rZ*)ON(=`V2GTHrP!{L!fMa zX|9x44GynY@VABBS(rg-bK8rZd&SChNq@rzqF~m4$(4F)cpI%{47N3Uey|Q~1>W`- z_@dO$g>-6`N={BNhn^3&P7@ehjd9(j#F;E5UrP3C8>EjW9wiN+uRq?Qc`5i-ml(~{ zt=oGP+AhmK#mMZwY$$m%J+aV(C!wV@x1YY+NVQ04`b^d?ja?aHXiu4DPS-^(&kqYF zSPme;dcntl5%H~#u?G$hy@Oxw$Brcvbf>aZyhcKLDkeYn;cj)c$uRZuUT|sF-e-Eq zO(t)u*0LsiZ$`#ZuZXZ&?%}oqN1T3}@gK`X$7J7cFX5xA_k9mpFujONY=N2*RXu4D zSflT$blg`kA5i=ORu>;hA_D`?g7ZWwo+t?9)25 z!E8~R({Q5R_ZJ#0bAy5Y6Wgrz`eI##C0`%=$^F!=S|%(or2;knty41>3+bM( z>a=H$Wbi>buxo=ra+@|qq~MzJnoi=co`+Q*6Q_L*QNY?=Z@zr%sP#I9odBnBNuTn# zE-K0Gjpz8uHmnLPL_&u7^W+ZqFC5vr{JE&CWH1 z>~$(-Md}@4HQ|2OZW5qj(Yrly9pp4}ovJ11V5^k$02_fbj10b1T5GAn+8o~h*1-OW z>*I-IZZnTPK<_Onwg%nf@mWM@4L7lw=cg_x>?9dXLWI2>i%O&|y^MIwGGxC4#|HxZ z9Q5%EP>Zyr#$#+F13nLGjTQy;@L|5 z=x^|>Aa&+g5QiZ4Xx_ygX-kY8pw{49RTHP;u0|cMs}2+0?}nF?8)}U18ZXU!n!#lw zY8O#eBJ}2nt2U}Ia148oSsHekA^vVU6-JlY`{hS-BYcQeVbS}x?3vl2L6Z!X{sd81 z^v7q(EIFtg)|{WZH!;Co z_x16!0&_(wKNA(_bntR7g-UQ{%v7+W$82p@2aX&8VY>nng$>jpWFj1L+SZ0LM%nQb zobwrK2syglX|PrA1cwklu-G}dr8Fsf!2HohlYH{D=7h*7+?z6N>Av5N<>l8?DJnMB z(^}JzY6N3(%1%Fq_jcLd2Kf9I1A9o*H@ZTXnTO8JLo$INX_{@|HqF|2qxJwE(O*Tr ztm|A!qLdx>;*mVCEqvhu@{xR&*|rsit>di&>eA5NblPwvj3yPRJa106NTPy>Vt*ZQtZ(%Mp@ndET{D`p&D}>r48x98B0p`>yf{Md;lnd z2ysHqqEHMYt0LcICPO4F7M+tM6k8zDm<;tq(OmGZq~3HkHv`R!?_O?sE=9A`PG~;TPEU#~a(axbscjTnjjyYn-W+QQ5uaIH z3w`#WIp{uU#)4ORnPaCX=xu+!(5Zj=Zt$Dw>bC5=#}`V$kovn`AE6NHh!Ln_E$fBr zA`%CMLy9^w`E(`i2oCx0;ilvF?FDQvi=?72`aVqJd4;sAxlq-EqqPOQOOCH^ra*DeBorfBC$crjm;q9(8EujBK9D!MR$*_) zls}CW6TQztv8sAOPXQr~a|>G8@8p^IC8rIr$me%9*f2Ifjy2w3l^0ekP2m-92NC)d zA+QiyrS8-QI(k{||9~6zS*T;BUsInyzq#Tn%)u|=SaQXISn4pVa~qju-0{Qe*bg1T z%4?$rNV`~mPmO=XL!YOb$IY(d_dJ@RALQGU$4d>Tzk`TL;d_l;9ax~)0cl;gy2CM}OjS_JdW?&`)6E{ZG!n zP@mX*BrHT`Oj`YZ^`4)?-C$UK;Yv2o8P7H^;R4y8y4zGeXK@-&J>Cn^@%*)OM0Aae z%*9kj+I7U`U~X9TtIUVmwG2&nboneXvgMcZedV+NtJXWl135U$Q6QK~jDzd%zthun z@`S0!oj2M$y~r`$7kc2vMG?wqA;p4c&hm9fku18>HE7tFwYu#-E_eW3YQvOB=@iZ0 zAxQq#JQbNHEJ-P~RFyZK-zJq3Q#o~%ohOJmi_yN%o%>5v91;ip-L}-?rDwF18#HcK zw$wep3nq!K1zk>dFNu&o->t3>^xE3v^>^G|ec=9u-XFIZDg}=5%l3h|FBa{rg3GfL zU!`ObE$E))qNUr+-*r(En$_zi1>c7v9XsfrKc0Ro$ZgNdE5L&F{xX!Eg@b)vi6xW) zs|aLI3+&ZKnz}>Hd&+ax0-cgO`aFKJ8?=> z21q%k1uB!uhO*brcIq-tmQlPvV$64R-sTl06fe&!g+1?~Xhl@L~^auCe zBx|@hT6-Tmh^uQF2gM%+PH^rG={pGc9#_SjE;*FvBVD&iY}jJRN?|DE{g&c)t(WW} zN5e7L{SoW2nEi1$I}f7rPRYNeI;4@(dEVHu@%jnsM-=TCA?l=|jGiLd9?wDJw6MXm z`8INHuHE-nh@N)f03j$;F?8FV{JQpqaaE$p^k-P>muSi+_XI<39O~8{ztOlx6`RMs z@=zDusm&b9z;_qePFG5jk>ki!4E_OmnX5fps`bs|v|!sAk&tXlroNKs%~Yw=nNXio zXHGU~-ftr}Vn@#@$cd=izx5IM)AyXiC!AWjlZ+3M%Mh5Hn;m3T#_V9x$CzcPGz zm;m3fYS8r}?0qC(Lz1;GWgsg$i3G*vdyk0l;0~X8c4QUbnbjuD54bmw>{qIq_ zpbL3RH0koLGoBTok{@A~q*$*HrJF_HMwm4gx1QE9J3^_PS>&DU*MknCJWKiOtpXL{ z+uYH)efcPOF~_uI@gi!{(bbpqR1;ku;=vzJ;b#&_BYv|mNRcXhcDNV`76g1D4Jl0w@O@2;E1# zx@18UcK+apjUwvCn*PLT@6inCYg&{nI%Dqk;w~V>>ad@_-@~%no3?}n`gv!6iHC?Bfyt36k+oA359*#< z&T;iX5+20umUUE%TgyP$=rwyMe0HSfXwhL-@Pp#dt?e`~!f6W}a0>5&zZS*;|&%vSmJi6>(og zE<0=e4^$(YuWv_{UdKBlJ*U9Z0{RJAgPx2g-q&-w`H=rgw5#Va@QmjM&5YMuO(|TC z2KS%NWnpdaj=G~X=z17up~#KmVd1|hSWe(U^OI`Z{n8CuuJgjfh^T}}F`f%u^ zLSEg}W$*Gze}7nZ-Za_rh+)%VVWG@Sl5RP3 zaa6p-4~%;SZ(3QG8J(uSTY2m25lV^YP$tgV2;wfcqC{BV!A~k6rS8|+?fXY>|6}DC z>Ds$OYCjwMea=Hw7ndj=FjQ&ky#U7lU>ZIzYhZs``7AQ%q+pbaW`zKT>IM1e?w zav+=gG^MW~VcD><2=Ic#?$0$fEUew+W!{rv9znMk+SPPcz2q&(Meek?bQM!OJWHCO zvApsCb)p;#61ek*neMLH#e6gIs`v!rx3`K1?Hb7aD#;>g06`#r*c2FHwN>hA`yq-`-* z$fq^kg%BsY9}J%wZQ&SyI<1Nsy_rhGCm3gA|MnTYibQ5GqvCE2;7Eo}iOI#kmGo{9Me z#eaEal(e%ND)r%CU^NtP@E{lQ;?}Xyx6YKtT{HhEzaIP;6{j_}D&K2CCj&S+gJX?E zy3;;gSi63AD7z-tLtpe>2c}|{!}ch!Juj(G$8J9iP^=R_tuBd^ABtY~H=5d1i;R7$ zFETkN$?sBlX3k~Qc`Dxi`ui&3w4}w8n(3`YO_M?AM;PmhH z<;8Z0jTDVl%l!tixj@Ips62N*&BN%fUqYJZq5a-DBs6CxvQ9YF??XN$SO@)7avD}(1qU%a9TiExJ>KOs&uB%(tw_z@ac~bo+)Px zzBM*#Bl0tPaJ-<^yD>Q((>fq)?>aQ z@=Ps!n;K(sTRlgo-;hF$w0w$kSKgC=DlWAM(2t9GJm!awET zJbmlDy6uan{+AooFYY$~Zr%&>i{PJ{^fx7#)M106 zIUnAtt2N8}OJTcnAmiw4nuKwze(LyY`$15+A?J?~<;;MEj-IAJukXuH_wA#+lQ=3O zsT?*U-UiWB}8P& zwQ}#c2(88C#6`&((tz-A60{(A^`Ohb8aKA+uPE*MR zmGHNrRf%v7=+u*^3cH9RZVsF8-a|Y-RJ=+N1*6%!YB54xc|j=)gI5M?a<%Dy_}m z*LOScg?%)>^uh3ll@G!wruROFHS~2{^m8Nr3M+>RXm)=NOQhs8f0cA?lIy18!dMmm zTcWFj_odFyX+D8Xm6M~{O_Ggb4XoZQTj;*_vX+}tc&;rWv^IlU@s4W~@&r2!_y1vK z#PtgN|9SvN3m6sz0EFch16UganE--Ru;(5CTjQ=AfQtdB?c=uyB-NZznu6QEB4GbMjRhF8EW0nCI7$O4PdgHLU2 z!3R1bz)Wa?ER7mOKuiRfBf}d;kN_7EVCl?n7)kygv|$G_H%3zZ2Lm{P=rD*LJVoO- zTHqc6teNZo)Ts~jmQH6!M2Ry zNuku7a<;Bt+^G5fJBPt9QAMqn3q9=Y8I?+xzDC%kqrkR!?F0E{ga>oJlvosv{;Pxn z-h2y{h^+U?!r32hIuwRD1YX>T4=f1NKceA5CT+kP6Tbk=OlfMY&nvBKm-^xEsbxXHd=q?=iNI6_T=FgM3#W0Ac| zjEt!D7kODY6}O1}QE!x#vaRiUg&SJOxA=cgDG>*m02ajwqR1WNti z;*}HFg22lSYvBS?A@Fl0#`_b&F1di>&^O^Nr-BT%fvAv>r6s?a;M++)9xiikK~r7< zkfo5Ipcxm)3h(siHB7wldNbJ*a zw0oqI1&dVGKG%};i9)Gk$c!X$^5WP-d5Bgyz(ib=8@4WvUx3F)&nl5c2K1=DI5^o# W!sP$GIv5@Z=p7%x1B(U$3H}E;eiya? delta 73317 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 Date: Sun, 16 Feb 2025 09:32:46 +0000 Subject: [PATCH 113/312] add usage to readme --- README.md | 88 ++++++++++++++++++-------------------------- docs/architecture.md | 35 ++++++++++++++++++ 2 files changed, 71 insertions(+), 52 deletions(-) create mode 100644 docs/architecture.md diff --git a/README.md b/README.md index f0562f9..abbbbe5 100644 --- a/README.md +++ b/README.md @@ -1,80 +1,64 @@ -# Euler Swap +# EulerSwap -EulerSwap is an Automated Market Maker (AMM) that uses [Euler Vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) as leveraged lending products in order to extend the range of its reserves and thereby improve the capital efficiency of liquidity provisioning. +EulerSwap is an Automated Market Maker (AMM) that uses [Euler lending vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) as leveraged lending products in order to extend the range of its reserves and thereby improve the capital efficiency of liquidity provisioning. -To swappers, Maglev presents a hopefully familiar Uniswap2-style interface but internally it supports borrow and repaying, custom pricing curves, and other advanced functionality. Although useable by anyone, it is primarily intended to be invoked by sophisticated actors such as swap aggregators, intents solvers, and MEV bots. Similar to Uniswap, there is a careful separation between the critical core functionality for servicing swaps and the surrounding periphery functions for quoting, etc. +To swappers, EulerSwap presents a hopefully familiar Uniswap2-style interface but internally it supports borrow and repaying, custom pricing curves, and other advanced functionality. Although useable by anyone, it is primarily intended to be invoked by sophisticated actors such as swap aggregators, intents solvers, and MEV bots. Similar to Uniswap, there is a careful separation between the critical core functionality for servicing swaps and the surrounding periphery functions for quoting, etc. - - - +For more information, refer to the [white paper](./docs/white-paper/EulerSwap_White_Paper.pdf). -- [Concept](#concept) -- [Operation](#operation) - - [Usage](#usage) - - [Virtual Reserves](#virtual-reserves) - - [Desynchronised Virtual Reserves](#desynchronised-virtual-reserves) -- [Curves](#curves) - - [Constant Sum](#constant-sum) - - [Constant Product](#constant-product) -- [License](#license) +## Usage - +EulerSwap comes with a comprehensive set of tests written in Solidity, which can be executed using Foundry. -## Concept +To install Foundry: -Given a fixed size investment, EulerSwap aims to increase the size of trades that can be serviced, relative to a conventional AMM such as Uniswap. It does this by borrowing the "out token" and collateralising this loan with the received "in token". Later on, when somebody wishes to swap in the reverse direction, the loan can be repaid in exchange for receiving the collateral, unwinding the borrow position. +```sh +curl -L https://foundry.paradigm.xyz | bash +``` -Because the total size of the position can be many times larger than the initial investment (depending on how much LTV/leverage is allowed on the underlying lending pools), the swap fees earned are multiplied. +This will download foundryup. To start Foundry, run: -The down-side is that while the AMM holds this leveraged position, it is paying interest on the loan. Fortunately, this is partially compensated by the fact that the AMM is simultaneously earning interest on the collateral. In some cases, this interest rate spread can be reduced further (occasionally even going negative) by taking advantage of incentives such as points/rewards. +```sh +foundryup +``` -## Operation +To clone the repo: -Since the level of acceptable borrowing risk may not be the same for every user, pooled deposits are not yet possible, and each EulerSwap instance manages funds for a single user (who of course may operate on behalf of pooled funds). +```sh +git clone https://github.com/euler-xyz/euler-swap.git && cd euler-swap +``` -EulerSwap is a contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators). This means that the user, known as the _holder_, does not give up control over their funds to a smart contract, but instead retains it in their wallet. The holder can be any compatible address, including standard multisig wallets or even an EOA. +## Testing -### Usage +### in `default` mode -The following are the high-level steps required to use EulerSwap: +To run the tests in a `default` mode: -- Deposit funds into one or both of the vaults -- Deploy the desired EulerSwap contract, choosing parameters such as the vaults and the desired `fee` -- Calculate the desired [virtual reserves](#virtual-reserves) and set these values by invoking `setVirtualReserves()` -- Install the EulerSwap contract as an operator for your account -- Invoke the `configure()` function on the EulerSwap contract +```sh +forge test +``` -At this point, anyone can invoke `swap()` on the EulerSwap contract, and this will perform borrowing and transferring activity between the two vaults. +### in `coverage` mode -### Debt Limits +```sh +forge coverage +``` -The initial deposits in the vaults represent the initial investment, and are swapped back and forth in response to swapping activity. In a conventional AMM such as Uniswap, these balance are called _reserves_. However, if swapping was constrained to these assets alone, then this would imply a hard limit on the size of swaps that can be serviced. To increase the effective funds, EulerSwap AMMs are configured with _virtual reserves_. These are typically larger than the size of the conventional reserves, which signifies that not only can all the assets be swapped from one vault to another, but even more assets can be borrowed on the EulerSwap's account. +## Safety -Virtual reserves control the maximum debt that the EulerSwap contract will attempt to acquire on each of its two vaults. Each vault can be configured independently. +This software is experimental and is provided "as is" and "as available". -For example, if the initial investment has a NAV of $1000, and virtual reserves are configured at $5000 for each vault, then the maximum LTV loan that the AMM will support will be `5000/6000 = 0.8333`. In order to leave a safety buffer, it is recommended to select a maximum LTV that is below the borrowing LTV of the vault. +No warranties are provided and no liability will be accepted for any loss incurred through the use of this codebase. -Note that it depends on the [curve](#curves) if the maximum LTV can actually be achieved. A constant product will only approach these reserve levels asymptotically, since each unit will get more and more expensive. However, with constant sum, this LTV can be achieved directly. +Always include thorough tests when using EulerSwap to ensure it interacts correctly with your code. -### Desynchronised Reserves +## Known limitations -The EulerSwap contract tracks what it believes the reserves to be by caching their values in storage. These reserves are updated on each swap. However, since the balance is not actually held by the EulerSwap contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest is accrued, or suddenly if the holder moves funds or the position is liquidated. +Refer to the [white paper](./docs/white-paper/EulerSwap_White_Paper.pdf) for a list of known limitations and security considerations. -When this occurs, the `syncVirtualReserves()` should be invoked. This determines the actual balances (and debts) of the holder, and adjusts them by the configured virtual reserve levels. +## Contributing -## Curves - -### Constant Sum - -This "curve" simply adds the values of the two reserves together and ensures that after a swap this sum has not decreased. This curve is mostly suitable for assets that are pegged to the same value, such as stable/stable pairs. - -This curve supports a price fraction so that the two tokens can have different relative values, which can be useful if the peg is other than 1:1, or if the tokens have differing decimals. - -In this curve, the entire virtual reserves can be consumed, and since each marginal unit of the swap has the same price, there is no direct incentive to deleverage the position. However, for the same reason this does allow fixed fees for swaps of any allowed size (fixed price impact). - -### Constant Product - -This is the traditional Uniswap2 curve that preserves the product of the two reserves. The larger a swap, the higher the price impact and the more profitable it is to arbitrage a disbalanced pool back to its wider market price. +The code is currently in an experimental phase. Feedback or ideas for improving EulerSwap are appreciated. Contributions are welcome from anyone interested in conducting security research, writing more tests including formal verification, improving readability and documentation, optimizing, simplifying, or developing integrations. ## License diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..404e5c1 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,35 @@ +# Architecture + +## Operation + +Since the level of acceptable borrowing risk may not be the same for every user, pooled deposits are not yet possible, and each EulerSwap instance manages funds for a single user (who of course may operate on behalf of pooled funds). + +EulerSwap is a contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators). This means that the user, known as the _holder_, does not give up control over their funds to a smart contract, but instead retains it in their wallet. The holder can be any compatible address, including standard multisig wallets or even an EOA. + +### Usage + +The following are the high-level steps required to use EulerSwap: + +- Deposit funds into one or both of the vaults +- Deploy the desired EulerSwap contract, choosing parameters such as the vaults and the desired `fee` +- Calculate the desired [virtual reserves](#virtual-reserves) and set these values by invoking `setVirtualReserves()` +- Install the EulerSwap contract as an operator for your account +- Invoke the `configure()` function on the EulerSwap contract + +At this point, anyone can invoke `swap()` on the EulerSwap contract, and this will perform borrowing and transferring activity between the two vaults. + +### Debt Limits + +The initial deposits in the vaults represent the initial investment, and are swapped back and forth in response to swapping activity. In a conventional AMM such as Uniswap, these balance are called _reserves_. However, if swapping was constrained to these assets alone, then this would imply a hard limit on the size of swaps that can be serviced. To increase the effective funds, EulerSwap AMMs are configured with _virtual reserves_. These are typically larger than the size of the conventional reserves, which signifies that not only can all the assets be swapped from one vault to another, but even more assets can be borrowed on the EulerSwap's account. + +Virtual reserves control the maximum debt that the EulerSwap contract will attempt to acquire on each of its two vaults. Each vault can be configured independently. + +For example, if the initial investment has a NAV of $1000, and virtual reserves are configured at $5000 for each vault, then the maximum LTV loan that the AMM will support will be `5000/6000 = 0.8333`. In order to leave a safety buffer, it is recommended to select a maximum LTV that is below the borrowing LTV of the vault. + +Note that it depends on the [curve](#curves) if the maximum LTV can actually be achieved. A constant product will only approach these reserve levels asymptotically, since each unit will get more and more expensive. However, with constant sum, this LTV can be achieved directly. + +### Desynchronised Reserves + +The EulerSwap contract tracks what it believes the reserves to be by caching their values in storage. These reserves are updated on each swap. However, since the balance is not actually held by the EulerSwap contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest is accrued, or suddenly if the holder moves funds or the position is liquidated. + +When this occurs, the `syncVirtualReserves()` should be invoked. This determines the actual balances (and debts) of the holder, and adjusts them by the configured virtual reserve levels. From 75e38c35972ef57884e4b6ab044ee62e97c7e832 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 16 Feb 2025 12:14:25 +0000 Subject: [PATCH 114/312] add interfaces docs --- docs/interfaces.md | 113 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 docs/interfaces.md diff --git a/docs/interfaces.md b/docs/interfaces.md new file mode 100644 index 0000000..c389f1e --- /dev/null +++ b/docs/interfaces.md @@ -0,0 +1,113 @@ +# EulerSwap interfaces + +## **IEulerSwap interface** + +### **Overview** + +The `IEulerSwap` interface defines the core functionality for executing token swaps, activating the contract, and verifying the swapping curve invariant. + +### **Functions** + +#### `swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;` + +- **description**: Optimistically sends the requested amounts of tokens to the `to` address, invokes `uniswapV2Call` callback on `to` (if `data` was provided), and then verifies that a sufficient amount of tokens were transferred to satisfy the swapping curve invariant. + +#### `activate() external;` + +- **description**: Approves the vaults to access the EulerSwap instance's tokens, and enables vaults as collateral. Can be invoked by anybody, and is harmless if invoked again. Calling this function is optional: EulerSwap can be activated on the first swap. + +#### `verify(uint256 newReserve0, uint256 newReserve1) external view returns (bool);` + +- **description**: Function that defines the shape of the swapping curve. Returns true if the specified reserve amounts would be acceptable (i.e., above and to-the-right of the swapping curve). + +### **Accessors** + +#### `curve() external view returns (bytes32);` + +- **description**: Returns the identifier of the swapping curve. + +#### `vault0() external view returns (address);` + +- **description**: Returns the address of vault 0. + +#### `vault1() external view returns (address);` + +- **description**: Returns the address of vault 1. + +#### `asset0() external view returns (address);` + +- **description**: Returns the address of asset 0. + +#### `asset1() external view returns (address);` + +- **description**: Returns the address of asset 1. + +#### `myAccount() external view returns (address);` + +- **description**: Returns the address of the account managing EulerSwap. + +#### `initialReserve0() external view returns (uint112);` + +- **description**: Returns the initial reserve amount of asset 0. + +#### `initialReserve1() external view returns (uint112);` + +- **description**: Returns the initial reserve amount of asset 1. + +#### `feeMultiplier() external view returns (uint256);` + +- **description**: Returns the fee multiplier applied to transactions. + +#### `getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 status);` + +- **description**: Retrieves the current reserve amounts and contract status. + +### **Curve accessors** + +#### `priceX() external view returns (uint256);` + +- **description**: Returns the price of asset X in terms of asset Y. + +#### `priceY() external view returns (uint256);` + +- **description**: Returns the price of asset Y in terms of asset X. + +#### `concentrationX() external view returns (uint256);` + +- **description**: Returns the liquidity concentration of asset X. + +#### `concentrationY() external view returns (uint256);` + +- **description**: Returns the liquidity concentration of asset Y. + +--- + +## **IEulerSwapPeriphery interface** + +### **Overview** + +The `IEulerSwapPeriphery` interface provides auxiliary functions for quoting token swap amounts before execution. + +### **Functions** + +#### `quoteExactInput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn) external view returns (uint256);` + +- **description**: Calculates how much `tokenOut` can be received for `amountIn` of `tokenIn`. + +#### `quoteExactOutput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut) external view returns (uint256);` + +- **description**: Calculates how much `tokenIn` is required to receive `amountOut` of `tokenOut`. + +--- + +## **IUniswapV2Callee interface** + +### **Overview** + +The `IUniswapV2Callee` interface defines the callback function used for executing swaps on EulerSwap. + +### **Functions** + +#### `uniswapV2Call(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external;` + +- **description**: Callback function invoked by EulerSwap during a swap operation, allowing the contract to perform additional logic. From 2f2682fe48f90ff9d20301f789bbaca9b391f9fb Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 16 Feb 2025 14:15:07 +0000 Subject: [PATCH 115/312] add overview and code structure to architecture docs --- docs/architecture.md | 125 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 105 insertions(+), 20 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 404e5c1..5889839 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,35 +1,120 @@ -# Architecture +# EulerSwap architecture -## Operation +# EulerSwap Architecture -Since the level of acceptable borrowing risk may not be the same for every user, pooled deposits are not yet possible, and each EulerSwap instance manages funds for a single user (who of course may operate on behalf of pooled funds). +## Overview -EulerSwap is a contract designed to be used as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators). This means that the user, known as the _holder_, does not give up control over their funds to a smart contract, but instead retains it in their wallet. The holder can be any compatible address, including standard multisig wallets or even an EOA. +EulerSwap is an automated market maker (AMM) that integrates with Euler lending vaults to provide deeper liquidity for swaps. -### Usage +Unlike traditional AMMs that use shared liquidity pools, EulerSwap operates with independent swap accounts, where each account manages liquidity for a single user or entity. -The following are the high-level steps required to use EulerSwap: +Each EulerSwap instance is a lightweight smart contract that functions as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators) while implementing a highly customizable AMM curve to determine swap output amounts. -- Deposit funds into one or both of the vaults -- Deploy the desired EulerSwap contract, choosing parameters such as the vaults and the desired `fee` -- Calculate the desired [virtual reserves](#virtual-reserves) and set these values by invoking `setVirtualReserves()` -- Install the EulerSwap contract as an operator for your account -- Invoke the `configure()` function on the EulerSwap contract +When a user initiates a swap, the swap account borrows the required output token using the input token as collateral. The swap account’s AMM curve governs the exchange rate, ensuring deep liquidity over short timeframes while maintaining a balance between collateral and debt over the long term. -At this point, anyone can invoke `swap()` on the EulerSwap contract, and this will perform borrowing and transferring activity between the two vaults. +## Code Structure -### Debt Limits +EulerSwap’s code is split into two main smart contracts: -The initial deposits in the vaults represent the initial investment, and are swapped back and forth in response to swapping activity. In a conventional AMM such as Uniswap, these balance are called _reserves_. However, if swapping was constrained to these assets alone, then this would imply a hard limit on the size of swaps that can be serviced. To increase the effective funds, EulerSwap AMMs are configured with _virtual reserves_. These are typically larger than the size of the conventional reserves, which signifies that not only can all the assets be swapped from one vault to another, but even more assets can be borrowed on the EulerSwap's account. +### EulerSwap core (`EulerSwap.sol`) -Virtual reserves control the maximum debt that the EulerSwap contract will attempt to acquire on each of its two vaults. Each vault can be configured independently. +- Handles collateralization via EVC and Euler lending vaults. +- Implements AMM curve invariant checks through the `verify()` function. -For example, if the initial investment has a NAV of $1000, and virtual reserves are configured at $5000 for each vault, then the maximum LTV loan that the AMM will support will be `5000/6000 = 0.8333`. In order to leave a safety buffer, it is recommended to select a maximum LTV that is below the borrowing LTV of the vault. +### EulerSwap periphery (`EulerSwapPeriphery.sol`) -Note that it depends on the [curve](#curves) if the maximum LTV can actually be achieved. A constant product will only approach these reserve levels asymptotically, since each unit will get more and more expensive. However, with constant sum, this LTV can be achieved directly. +- Provides simplified functions for retrieving swap quotes from the AMM curve. +- Acts as a convenience layer for external integrations. -### Desynchronised Reserves +## Operational flow -The EulerSwap contract tracks what it believes the reserves to be by caching their values in storage. These reserves are updated on each swap. However, since the balance is not actually held by the EulerSwap contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest is accrued, or suddenly if the holder moves funds or the position is liquidated. +The following steps outline how a swap account is created and configured: -When this occurs, the `syncVirtualReserves()` should be invoked. This determines the actual balances (and debts) of the holder, and adjusts them by the configured virtual reserve levels. +1. Deposit initial liquidity into one or both of the vaults to enable swaps. +2. Deploy the EulerSwap contract, specifying AMM curve parameters and the `fee`. +3. Set the [virtual reserves](#virtual-reserves) by invoking `setVirtualReserves()`. +4. Install the EulerSwap contract as an operator for the user's account. +5. Invoke the `configure()` function on the EulerSwap contract. + +Once configured, the EulerSwap contract can process swaps. When a user invokes `swap()`, the contract facilitates borrowing and transfers between the underlying vaults as dictated by the AMM curve. + +### Virtual reserves + +The initial deposits in the vaults provide starting liquidity and facilitate swaps. In traditional AMMs like Uniswap, these balances are known as _reserves_. +However, relying solely on these assets would impose a hard limit on swap size. To overcome this, EulerSwap introduces _virtual reserves_, allowing the AMM to extend its effective liquidity by borrowing against its real reserves. + +Virtual reserves control the maximum debt that the EulerSwap contract will attempt to acquire on each of its two vaults. Each vault can be configured independently. For example, if the initial investment has a NAV of \$1000, and virtual reserves are configured at \$5000 for each vault, then the maximum LTV loan that the AMM will support will be `5000/6000 = 0.8333`. In order to leave a safety buffer, it is recommended to select a maximum LTV that is below the borrowing LTV of the vault. Note that it depends on the [curve](#curves) if the maximum LTV can actually be achieved. A constant product curve will only approach these reserve levels asymptotically, since each unit will get more and more expensive. However, with a constant sum curve, the maximum LTV can be achieved directly. + +### Reserve synchronisation + +The EulerSwap contract tracks what it believes the reserves to be by caching their values in storage. These reserves are updated on each swap. However, since the balance is not actually held by the EulerSwap contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest is accrued, or suddenly if the holder moves funds or the position is liquidated. When this occurs, the `syncVirtualReserves()` should be invoked. This determines the actual balances (and debts) of the holder and adjusts them by the configured virtual reserve levels. + +## Components + +### **1. Core contracts** + +#### **Maglev contract** + +The `Maglev` contract is the core of EulerSwap and is responsible for: + +- Managing liquidity reserves. +- Executing token swaps based on the EulerSwap curve. +- Enforcing collateralization through EVC. +- Maintaining vault and asset associations. + +##### **Key features** + +- Implements a unique **swapping curve** that ensures efficient liquidity provision. +- Handles **collateralized borrowing** via vaults. +- Enforces a **fee multiplier** to apply swap fees. +- Implements a **non-reentrant mechanism** to prevent recursive calls. + +##### **Key functions** + +- `activate()`: Initializes vault approvals and enables collateral. +- `swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data)`: Performs asset swaps and enforces curve constraints. +- `verify(uint256 newReserve0, uint256 newReserve1)`: Ensures reserves conform to the defined curve. +- `f(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c)`: Defines the EulerSwap curve formula for swaps. + +### **2. Periphery contracts** + +#### **MaglevPeriphery contract** + +The `MaglevPeriphery` contract extends the functionality of the core Maglev contract by providing: + +- **Swap price quotations** before execution. +- **Liquidity checks** to ensure solvency before transactions. +- **Binary search mechanisms** for dynamic price calculation. + +##### **Key functions** + +- `quoteExactInput(address maglev, address tokenIn, address tokenOut, uint256 amountIn)`: Estimates the output amount for a given input. +- `quoteExactOutput(address maglev, address tokenIn, address tokenOut, uint256 amountOut)`: Estimates the required input amount to receive a specified output. +- `computeQuote(IMaglev maglev, address tokenIn, address tokenOut, uint256 amount, bool exactIn)`: A high-level function to compute swaps while enforcing fee multipliers. +- `binarySearch(IMaglev maglev, uint112 reserve0, uint112 reserve1, uint256 amount, bool exactIn, bool asset0IsInput)`: Uses binary search to determine an optimal swap amount along the curve. + +### **3. Vault integration** + +EulerSwap integrates with **Ethereum Vault Connector (EVC)** to enable collateralized trading. Each liquidity vault manages asset balances, borrowing, and repayment, ensuring: + +- **Controlled debt exposure** +- **Dynamic liquidity reserves** +- **Secure vault interactions** + +### **4. Security mechanisms** + +- **Non-reentrant protection**: Ensures swaps do not trigger recursive calls. +- **Collateral verification**: Uses EVC to verify and adjust collateral balances. +- **Curve constraints enforcement**: Prevents swap execution that violates the defined curve invariant. +- **Precision safeguards**: Fixed-point arithmetic (`1e18` scaling) ensures precision in calculations. + +## Summary + +EulerSwap’s architecture is designed for **efficient, secure, and collateral-backed trading** with a custom **swapping curve**. The system leverages: + +- **Maglev** as the core AMM contract. +- **MaglevPeriphery** for auxiliary quoting and validations. +- **Ethereum Vault Connector (EVC)** for collateralized vault management. +- **Security-focused design** to prevent vulnerabilities in asset handling. + +This modular and scalable architecture ensures that EulerSwap provides robust DeFi trading functionality while maintaining security and efficiency. From 4f031d487f20671396090965e6fe45238bb767cc Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 16 Feb 2025 14:27:36 +0000 Subject: [PATCH 116/312] fix: typos in architecture.md --- docs/architecture.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 5889839..11ebe01 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,7 +1,5 @@ # EulerSwap architecture -# EulerSwap Architecture - ## Overview EulerSwap is an automated market maker (AMM) that integrates with Euler lending vaults to provide deeper liquidity for swaps. @@ -12,7 +10,7 @@ Each EulerSwap instance is a lightweight smart contract that functions as an [EV When a user initiates a swap, the swap account borrows the required output token using the input token as collateral. The swap account’s AMM curve governs the exchange rate, ensuring deep liquidity over short timeframes while maintaining a balance between collateral and debt over the long term. -## Code Structure +## Code structure EulerSwap’s code is split into two main smart contracts: From 2bd922b925ba1ffcc4d0d2746e14aaf5ed131302 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Sun, 16 Feb 2025 16:44:49 +0100 Subject: [PATCH 117/312] chore: rename to EulerSwap --- TODO | 40 ------- src/{Maglev.sol => EulerSwap.sol} | 18 +-- ...evPeriphery.sol => EulerSwapPeriphery.sol} | 43 +++---- .../{IMaglev.sol => IEulerSwap.sol} | 8 +- ...vPeriphery.sol => IEulerSwapPeriphery.sol} | 6 +- test/AltDecimals.t.sol | 80 +++++-------- .../{MaglevTest.t.sol => EulerSwapTest.t.sol} | 113 +++++++----------- ...TestBase.t.sol => EulerSwapTestBase.t.sol} | 46 ++++--- test/PreserveNav.t.sol | 60 +++------- test/UniswapV2Call.t.sol | 40 ++----- 10 files changed, 170 insertions(+), 284 deletions(-) delete mode 100644 TODO rename src/{Maglev.sol => EulerSwap.sol} (95%) rename src/{MaglevPeriphery.sol => EulerSwapPeriphery.sol} (69%) rename src/interfaces/{IMaglev.sol => IEulerSwap.sol} (88%) rename src/interfaces/{IMaglevPeriphery.sol => IEulerSwapPeriphery.sol} (58%) rename test/{MaglevTest.t.sol => EulerSwapTest.t.sol} (54%) rename test/{MaglevTestBase.t.sol => EulerSwapTestBase.t.sol} (78%) diff --git a/TODO b/TODO deleted file mode 100644 index 87d684f..0000000 --- a/TODO +++ /dev/null @@ -1,40 +0,0 @@ -! Don't make quotes that would cause a swap to fail if supply/borrow caps exceeded -* Better revert messages when a swap fails due to maglev debt-limit/vault utilisation/etc - * currently it's an arithmetic underflow - - -TESTING - -* when exchange rate in vaults != 1 -* uniswap callback, flash swaps -* hitting reserve/utilisation limits -* AssetsOutOfOrderOrEqual - - -MISC - -? A really small swap could fail because deposit() results in 0 shares, which causes EVK to revert. Call convertToShares() first? Seems like overkill... -? permit2 instead of regular approval: measure gas savings -* Improve the efficiency of on-chain quoting - * Probably necessary for supporting non-zero slippage swaps - * Use unchecked math in verify() (needs careful boundary analysis) - * Closed-form quoting solutions - * "Range hints" for the binary search - - -IDEAS - -* Currently we have only been supporting stable-stable pairs - * What extra considerations would there be for floating pairs? -* Automatically re-invest fees? There are a few options: - * Don't do anything: Re-deploing probably isn't a huge deal - * Increase the reserves by the fee amount - * Increase the reserves by the extra amount of possible leverage supported by the new fee - * Apply fees to a super-concentrated middle section of the curve (needs R&D) -* Could current reserves be calculated dynamically based on balances/debts/debt limits? - * I guess you would lose a chunk of interest to arbitrage - * Donation attacks? -* What can we do to make this easily integrated with aggregators/MEV bots/etc? - * How to handle a discovery/tracking of the different Maglev instances? - ? Factory? Registry? Maybe a fake factory that reads the actually installed operators from a set of addresses? - ? Transparent proxy so a Maglev address can stay constant diff --git a/src/Maglev.sol b/src/EulerSwap.sol similarity index 95% rename from src/Maglev.sol rename to src/EulerSwap.sol index 0f567e7..6b0556f 100644 --- a/src/Maglev.sol +++ b/src/EulerSwap.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; -import {EVCUtil} from "evc/utils/EVCUtil.sol"; import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault, IERC20, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; import {IUniswapV2Callee} from "./interfaces/IUniswapV2Callee.sol"; -import {IMaglev} from "./interfaces/IMaglev.sol"; +import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; +import {EVCUtil} from "evc/utils/EVCUtil.sol"; -contract Maglev is IMaglev, EVCUtil { +contract EulerSwap is IEulerSwap, EVCUtil { bytes32 public constant curve = keccak256("EulerSwap v1"); address public immutable vault0; @@ -37,7 +37,7 @@ contract Maglev is IMaglev, EVCUtil { error AssetsOutOfOrderOrEqual(); error CurveViolation(); - event MaglevCreated(address indexed maglev, address indexed asset0, address indexed asset1); + event EulerSwapCreated(address indexed eulerSwap, address indexed asset0, address indexed asset1); event Swap( address indexed sender, @@ -76,7 +76,7 @@ contract Maglev is IMaglev, EVCUtil { } constructor(Params memory params, CurveParams memory curveParams) EVCUtil(params.evc) { - // Maglev params + // EulerSwap params require(params.fee < 1e18, BadFee()); @@ -106,10 +106,10 @@ contract Maglev is IMaglev, EVCUtil { concentrationX = curveParams.concentrationX; concentrationY = curveParams.concentrationY; - emit MaglevCreated(address(this), asset0Addr, asset1Addr); + emit EulerSwapCreated(address(this), asset0Addr, asset1Addr); } - /// @inheritdoc IMaglev + /// @inheritdoc IEulerSwap function activate() public { require(status != 2, Locked()); status = 1; @@ -126,7 +126,7 @@ contract Maglev is IMaglev, EVCUtil { return y0 + px * 1e18 / py * (c * (2 * x0 - xt) / 1e18 + (1e18 - c) * x0 / 1e18 * x0 / xt - x0) / 1e18; } - /// @inheritdoc IMaglev + /// @inheritdoc IEulerSwap function verify(uint256 newReserve0, uint256 newReserve1) public view returns (bool) { if (newReserve0 >= initialReserve0) { if (newReserve1 >= initialReserve1) return true; @@ -137,7 +137,7 @@ contract Maglev is IMaglev, EVCUtil { } } - /// @inheritdoc IMaglev + /// @inheritdoc IEulerSwap function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external callThroughEVC diff --git a/src/MaglevPeriphery.sol b/src/EulerSwapPeriphery.sol similarity index 69% rename from src/MaglevPeriphery.sol rename to src/EulerSwapPeriphery.sol index 930aa93..2354818 100644 --- a/src/MaglevPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.27; import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; -import {IMaglev} from "./interfaces/IMaglev.sol"; -import {IMaglevPeriphery} from "./interfaces/IMaglevPeriphery.sol"; +import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; +import {IEulerSwapPeriphery} from "./interfaces/IEulerSwapPeriphery.sol"; -contract MaglevPeriphery is IMaglevPeriphery { +contract EulerSwapPeriphery is IEulerSwapPeriphery { address private immutable evc; constructor(address evc_) { @@ -18,52 +18,54 @@ contract MaglevPeriphery is IMaglevPeriphery { error InsufficientReserves(); error InsufficientCash(); - /// @inheritdoc IMaglevPeriphery - function quoteExactInput(address maglev, address tokenIn, address tokenOut, uint256 amountIn) + /// @inheritdoc IEulerSwapPeriphery + function quoteExactInput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn) external view returns (uint256) { - return computeQuote(IMaglev(maglev), tokenIn, tokenOut, amountIn, true); + return computeQuote(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountIn, true); } - /// @inheritdoc IMaglevPeriphery - function quoteExactOutput(address maglev, address tokenIn, address tokenOut, uint256 amountOut) + /// @inheritdoc IEulerSwapPeriphery + function quoteExactOutput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut) external view returns (uint256) { - return computeQuote(IMaglev(maglev), tokenIn, tokenOut, amountOut, false); + return computeQuote(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountOut, false); } /// @dev High-level quoting function. It handles fees and performs /// state validation, for example that there is sufficient cash available. - function computeQuote(IMaglev maglev, address tokenIn, address tokenOut, uint256 amount, bool exactIn) + function computeQuote(IEulerSwap eulerSwap, address tokenIn, address tokenOut, uint256 amount, bool exactIn) internal view returns (uint256) { - require(IEVC(evc).isAccountOperatorAuthorized(maglev.myAccount(), address(maglev)), OperatorNotInstalled()); + require( + IEVC(evc).isAccountOperatorAuthorized(eulerSwap.myAccount(), address(eulerSwap)), OperatorNotInstalled() + ); - uint256 feeMultiplier = maglev.feeMultiplier(); - address vault0 = maglev.vault0(); - address vault1 = maglev.vault1(); - (uint112 reserve0, uint112 reserve1,) = maglev.getReserves(); + uint256 feeMultiplier = eulerSwap.feeMultiplier(); + address vault0 = eulerSwap.vault0(); + address vault1 = eulerSwap.vault1(); + (uint112 reserve0, uint112 reserve1,) = eulerSwap.getReserves(); // exactIn: decrease received amountIn, rounding down if (exactIn) amount = amount * feeMultiplier / 1e18; bool asset0IsInput; { - address asset0 = maglev.asset0(); - address asset1 = maglev.asset1(); + address asset0 = eulerSwap.asset0(); + address asset1 = eulerSwap.asset1(); if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true; else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; else revert UnsupportedPair(); } - uint256 quote = binarySearch(maglev, reserve0, reserve1, amount, exactIn, asset0IsInput); + uint256 quote = binarySearch(eulerSwap, reserve0, reserve1, amount, exactIn, asset0IsInput); if (exactIn) { // if `exactIn`, `quote` is the amount of assets to buy from the AMM @@ -85,7 +87,7 @@ contract MaglevPeriphery is IMaglevPeriphery { /// Although some curves may have more efficient closed-form solutions, /// this works with any monotonic curve. function binarySearch( - IMaglev maglev, + IEulerSwap eulerSwap, uint112 reserve0, uint112 reserve1, uint256 amount, @@ -112,7 +114,8 @@ contract MaglevPeriphery is IMaglevPeriphery { while (low < high) { uint256 mid = (low + high) / 2; - if (dy == 0 ? maglev.verify(uint256(reserve0New), mid) : maglev.verify(mid, uint256(reserve1New))) { + if (dy == 0 ? eulerSwap.verify(uint256(reserve0New), mid) : eulerSwap.verify(mid, uint256(reserve1New))) + { high = mid; } else { low = mid + 1; diff --git a/src/interfaces/IMaglev.sol b/src/interfaces/IEulerSwap.sol similarity index 88% rename from src/interfaces/IMaglev.sol rename to src/interfaces/IEulerSwap.sol index 0d54352..c9a9865 100644 --- a/src/interfaces/IMaglev.sol +++ b/src/interfaces/IEulerSwap.sol @@ -1,16 +1,16 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.0; -interface IMaglev { +interface IEulerSwap { /// @notice Optimistically sends the requested amounts of tokens to the `to` /// address, invokes `uniswapV2Call` callback on `to` (if `data` was provided), /// and then verifies that a sufficient amount of tokens were transferred to /// satisfy the swapping curve invariant. function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; - /// @notice Approves the vaults to access the Maglev instance's tokens, and enables + /// @notice Approves the vaults to access the EulerSwap instance's tokens, and enables /// vaults as collateral. Can be invoked by anybody, and is harmless if invoked again. - /// Calling this function is optional: Maglev can be activated on the first swap. + /// Calling this function is optional: EulerSwap can be activated on the first swap. function activate() external; /// @notice Function that defines the shape of the swapping curve. Returns true iff @@ -18,7 +18,7 @@ interface IMaglev { /// of the swapping curve). function verify(uint256 newReserve0, uint256 newReserve1) external view returns (bool); - // Maglev Accessors + // EulerSwap Accessors function curve() external view returns (bytes32); function vault0() external view returns (address); diff --git a/src/interfaces/IMaglevPeriphery.sol b/src/interfaces/IEulerSwapPeriphery.sol similarity index 58% rename from src/interfaces/IMaglevPeriphery.sol rename to src/interfaces/IEulerSwapPeriphery.sol index 3b6f5c8..99c97e7 100644 --- a/src/interfaces/IMaglevPeriphery.sol +++ b/src/interfaces/IEulerSwapPeriphery.sol @@ -1,15 +1,15 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.0; -interface IMaglevPeriphery { +interface IEulerSwapPeriphery { /// @notice How much `tokenOut` can I get for `amountIn` of `tokenIn`? - function quoteExactInput(address maglev, address tokenIn, address tokenOut, uint256 amountIn) + function quoteExactInput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn) external view returns (uint256); /// @notice How much `tokenIn` do I need to get `amountOut` of `tokenOut`? - function quoteExactOutput(address maglev, address tokenIn, address tokenOut, uint256 amountOut) + function quoteExactOutput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut) external view returns (uint256); diff --git a/test/AltDecimals.t.sol b/test/AltDecimals.t.sol index 069d1de..9079885 100644 --- a/test/AltDecimals.t.sol +++ b/test/AltDecimals.t.sol @@ -1,118 +1,92 @@ // SPDX-License-Identifier: GPL-2.0-or-later - pragma solidity ^0.8.24; -import {Test, console} from "forge-std/Test.sol"; - -import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; -import {IEVault} from "evk/EVault/IEVault.sol"; -import {MaglevTestBase} from "./MaglevTestBase.t.sol"; - -import {Maglev} from "../src/Maglev.sol"; +import {IEVault, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; -contract AltDecimals is MaglevTestBase { - Maglev public maglev; +contract AltDecimals is EulerSwapTestBase { + EulerSwap public eulerSwap; function setUp() public virtual override { super.setUp(); } - function createMaglev( - uint112 debtLimitA, - uint112 debtLimitB, - uint256 fee, - uint256 px, - uint256 py, - uint256 cx, - uint256 cy - ) internal { - vm.prank(creator); - maglev = new Maglev( - getMaglevParams(debtLimitA, debtLimitB, fee), - Maglev.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) - ); - - vm.prank(holder); - evc.setAccountOperator(holder, address(maglev), true); - } - function test_alt_decimals_6_18_in() public { - createMaglev(50e6, 50e18, 0, 1e18, 1e6, 0.9e18, 0.9e18); - skimAll(maglev, true); + eulerSwap = createEulerSwap(50e6, 50e18, 0, 1e18, 1e6, 0.9e18, 0.9e18); + skimAll(eulerSwap, true); uint256 amount = 1e6; - uint256 q = periphery.quoteExactInput(address(maglev), address(assetTST), address(assetTST2), amount); + uint256 q = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amount); assertApproxEqAbs(q, 1e18, 0.01e18); assetTST.mint(address(this), amount); - assetTST.transfer(address(maglev), amount); + assetTST.transfer(address(eulerSwap), amount); { uint256 qPlus = q + 1; vm.expectRevert(); - maglev.swap(0, qPlus, address(this), ""); + eulerSwap.swap(0, qPlus, address(this), ""); } - maglev.swap(0, q, address(this), ""); + eulerSwap.swap(0, q, address(this), ""); } function test_alt_decimals_6_18_out() public { - createMaglev(50e6, 50e18, 0, 1e18, 1e6, 0.9e18, 0.9e18); - skimAll(maglev, true); + eulerSwap = createEulerSwap(50e6, 50e18, 0, 1e18, 1e6, 0.9e18, 0.9e18); + skimAll(eulerSwap, true); uint256 amount = 1e18; - uint256 q = periphery.quoteExactOutput(address(maglev), address(assetTST), address(assetTST2), amount); + uint256 q = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amount); assertApproxEqAbs(q, 1e6, 0.01e6); assetTST.mint(address(this), q); - assetTST.transfer(address(maglev), q); + assetTST.transfer(address(eulerSwap), q); { uint256 amountPlus = amount + 0.0000001e18; vm.expectRevert(); - maglev.swap(0, amountPlus, address(this), ""); + eulerSwap.swap(0, amountPlus, address(this), ""); } - maglev.swap(0, amount, address(this), ""); + eulerSwap.swap(0, amount, address(this), ""); } function test_alt_decimals_18_6_in() public { - createMaglev(50e18, 50e6, 0, 1e6, 1e18, 0.9e18, 0.9e18); - skimAll(maglev, true); + eulerSwap = createEulerSwap(50e18, 50e6, 0, 1e6, 1e18, 0.9e18, 0.9e18); + skimAll(eulerSwap, true); uint256 amount = 1e18; - uint256 q = periphery.quoteExactInput(address(maglev), address(assetTST), address(assetTST2), amount); + uint256 q = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amount); assertApproxEqAbs(q, 1e6, 0.01e6); assetTST.mint(address(this), amount); - assetTST.transfer(address(maglev), amount); + assetTST.transfer(address(eulerSwap), amount); { uint256 qPlus = q + 1; vm.expectRevert(); - maglev.swap(0, qPlus, address(this), ""); + eulerSwap.swap(0, qPlus, address(this), ""); } - maglev.swap(0, q, address(this), ""); + eulerSwap.swap(0, q, address(this), ""); } function test_alt_decimals_18_6_out() public { - createMaglev(50e18, 50e6, 0, 1e6, 1e18, 0.9e18, 0.9e18); - skimAll(maglev, false); + eulerSwap = createEulerSwap(50e18, 50e6, 0, 1e6, 1e18, 0.9e18, 0.9e18); + skimAll(eulerSwap, false); uint256 amount = 1e6; - uint256 q = periphery.quoteExactOutput(address(maglev), address(assetTST), address(assetTST2), amount); + uint256 q = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amount); assertApproxEqAbs(q, 1e18, 0.01e18); assetTST.mint(address(this), q); - assetTST.transfer(address(maglev), q); + assetTST.transfer(address(eulerSwap), q); { uint256 amountPlus = amount + 1; vm.expectRevert(); - maglev.swap(0, amountPlus, address(this), ""); + eulerSwap.swap(0, amountPlus, address(this), ""); } - maglev.swap(0, amount, address(this), ""); + eulerSwap.swap(0, amount, address(this), ""); } } diff --git a/test/MaglevTest.t.sol b/test/EulerSwapTest.t.sol similarity index 54% rename from test/MaglevTest.t.sol rename to test/EulerSwapTest.t.sol index fdb00b1..d81e85f 100644 --- a/test/MaglevTest.t.sol +++ b/test/EulerSwapTest.t.sol @@ -1,48 +1,22 @@ // SPDX-License-Identifier: GPL-2.0-or-later - pragma solidity ^0.8.24; -import {Test, console} from "forge-std/Test.sol"; - -import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; -import {IEVault} from "evk/EVault/IEVault.sol"; -import {MaglevTestBase} from "./MaglevTestBase.t.sol"; +import {IEVault, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; -import {Maglev} from "../src/Maglev.sol"; - -contract MaglevTest is MaglevTestBase { - Maglev public maglev; +contract EulerSwapTest is EulerSwapTestBase { + EulerSwap public eulerSwap; function setUp() public virtual override { super.setUp(); - createMaglev(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); - } - - function createMaglev( - uint112 debtLimitA, - uint112 debtLimitB, - uint256 fee, - uint256 px, - uint256 py, - uint256 cx, - uint256 cy - ) internal { - vm.prank(creator); - maglev = new Maglev( - getMaglevParams(debtLimitA, debtLimitB, fee), - Maglev.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) - ); - - vm.prank(holder); - evc.setAccountOperator(holder, address(maglev), true); + eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); } function test_different_EVC() public { - vm.expectRevert(Maglev.DifferentEVC.selector); + vm.expectRevert(EulerSwap.DifferentEVC.selector); - new Maglev( - Maglev.Params({ + new EulerSwap( + EulerSwap.Params({ evc: address(makeAddr("RANDOM_EVC")), vault0: address(eTST), vault1: address(eTST2), @@ -51,32 +25,34 @@ contract MaglevTest is MaglevTestBase { debtLimit1: 50e18, fee: 0 }), - Maglev.CurveParams({priceX: 1e18, priceY: 1e18, concentrationX: 4e18, concentrationY: 0.85e18}) + EulerSwap.CurveParams({priceX: 1e18, priceY: 1e18, concentrationX: 4e18, concentrationY: 0.85e18}) ); } function test_basicSwap_exactIn() public monotonicHolderNAV { uint256 amountIn = 1e18; - uint256 amountOut = periphery.quoteExactInput(address(maglev), address(assetTST), address(assetTST2), amountIn); + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); assertApproxEqAbs(amountOut, 0.9974e18, 0.0001e18); assetTST.mint(address(this), amountIn); - assetTST.transfer(address(maglev), amountIn); - maglev.swap(0, amountOut, address(this), ""); + assetTST.transfer(address(eulerSwap), amountIn); + eulerSwap.swap(0, amountOut, address(this), ""); assertEq(assetTST2.balanceOf(address(this)), amountOut); } function test_basicSwap_exactOut() public monotonicHolderNAV { uint256 amountOut = 1e18; - uint256 amountIn = periphery.quoteExactOutput(address(maglev), address(assetTST), address(assetTST2), amountOut); + uint256 amountIn = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); assertApproxEqAbs(amountIn, 1.0025e18, 0.0001e18); assetTST.mint(address(this), amountIn); - assetTST.transfer(address(maglev), amountIn); - maglev.swap(0, amountOut, address(this), ""); + assetTST.transfer(address(eulerSwap), amountIn); + eulerSwap.swap(0, amountOut, address(this), ""); assertEq(assetTST2.balanceOf(address(this)), amountOut); } @@ -90,15 +66,16 @@ contract MaglevTest is MaglevTestBase { int256 origNAV = getHolderNAV(); - createMaglev(50e18, 50e18, 0, px, py, 0.4e18, 0.85e18); + eulerSwap = createEulerSwap(50e18, 50e18, 0, px, py, 0.4e18, 0.85e18); uint256 amountIn = 1e18; - uint256 amountOut = periphery.quoteExactInput(address(maglev), address(assetTST), address(assetTST2), amountIn); + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); assetTST.mint(address(this), amountIn); - assetTST.transfer(address(maglev), amountIn); - maglev.swap(0, amountOut, address(this), ""); + assetTST.transfer(address(eulerSwap), amountIn); + eulerSwap.swap(0, amountOut, address(this), ""); assertEq(assetTST2.balanceOf(address(this)), amountOut); assertGe(getHolderNAV(), origNAV); @@ -114,18 +91,18 @@ contract MaglevTest is MaglevTestBase { t1.mint(address(this), amount); - uint256 q = periphery.quoteExactInput(address(maglev), address(t1), address(t2), amount); + uint256 q = periphery.quoteExactInput(address(eulerSwap), address(t1), address(t2), amount); - t1.transfer(address(maglev), amount); - if (dir) maglev.swap(0, q, address(this), ""); - else maglev.swap(q, 0, address(this), ""); + t1.transfer(address(eulerSwap), amount); + if (dir) eulerSwap.swap(0, q, address(this), ""); + else eulerSwap.swap(q, 0, address(this), ""); assertEq(t2.balanceOf(address(this)), q); - t2.transfer(address(maglev), q); - if (dir) maglev.swap(amount, 0, address(this), ""); - else maglev.swap(0, amount, address(this), ""); + t2.transfer(address(eulerSwap), q); + if (dir) eulerSwap.swap(amount, 0, address(this), ""); + else eulerSwap.swap(0, amount, address(this), ""); - uint256 q2 = periphery.quoteExactInput(address(maglev), address(t1), address(t2), amount); + uint256 q2 = periphery.quoteExactInput(address(eulerSwap), address(t1), address(t2), amount); assertEq(q, q2); } @@ -142,7 +119,7 @@ contract MaglevTest is MaglevTestBase { oracle.setPrice(address(eTST), unitOfAccount, price); oracle.setPrice(address(assetTST), unitOfAccount, price); - createMaglev(50e18, 50e18, 0, px, py, cx, cy); + eulerSwap = createEulerSwap(50e18, 50e18, 0, px, py, cx, cy); } int256 origNAV = getHolderNAV(); @@ -153,19 +130,19 @@ contract MaglevTest is MaglevTestBase { else (t1, t2) = (assetTST2, assetTST); t1.mint(address(this), amount); - uint256 q = periphery.quoteExactInput(address(maglev), address(t1), address(t2), amount); + uint256 q = periphery.quoteExactInput(address(eulerSwap), address(t1), address(t2), amount); - t1.transfer(address(maglev), amount); - if (dir) maglev.swap(0, q, address(this), ""); - else maglev.swap(q, 0, address(this), ""); + t1.transfer(address(eulerSwap), amount); + if (dir) eulerSwap.swap(0, q, address(this), ""); + else eulerSwap.swap(q, 0, address(this), ""); assertEq(t2.balanceOf(address(this)), q); t2.mint(address(this), amount2); - uint256 q2 = periphery.quoteExactInput(address(maglev), address(t2), address(t1), amount2); + uint256 q2 = periphery.quoteExactInput(address(eulerSwap), address(t2), address(t1), amount2); - t2.transfer(address(maglev), amount2); - if (dir) maglev.swap(q2, 0, address(this), ""); - else maglev.swap(0, q2, address(this), ""); + t2.transfer(address(eulerSwap), amount2); + if (dir) eulerSwap.swap(q2, 0, address(this), ""); + else eulerSwap.swap(0, q2, address(this), ""); assertEq(t1.balanceOf(address(this)), q2); assertGe(getHolderNAV(), origNAV); @@ -178,7 +155,7 @@ contract MaglevTest is MaglevTestBase { cy = bound(cy, 0.01e18, 0.99e18); fee = bound(fee, 0, 0.1e18); - createMaglev(50e18, 50e18, fee, 1e18, 1e18, cx, cy); + eulerSwap = createEulerSwap(50e18, 50e18, fee, 1e18, 1e18, cx, cy); int256 origNAV = getHolderNAV(); @@ -192,24 +169,24 @@ contract MaglevTest is MaglevTestBase { else (t1, t2) = (assetTST2, assetTST); t1.mint(address(this), amount); - uint256 q = periphery.quoteExactInput(address(maglev), address(t1), address(t2), amount); + uint256 q = periphery.quoteExactInput(address(eulerSwap), address(t1), address(t2), amount); // Try to swap out 1 extra - t1.transfer(address(maglev), amount); + t1.transfer(address(eulerSwap), amount); { uint256 qPlus = q + 1; vm.expectRevert(); - if (dir) maglev.swap(0, qPlus, address(this), ""); - else maglev.swap(qPlus, 0, address(this), ""); + if (dir) eulerSwap.swap(0, qPlus, address(this), ""); + else eulerSwap.swap(qPlus, 0, address(this), ""); } // Confirm actual quote works uint256 prevBal = t2.balanceOf(address(this)); - if (dir) maglev.swap(0, q, address(this), ""); - else maglev.swap(q, 0, address(this), ""); + if (dir) eulerSwap.swap(0, q, address(this), ""); + else eulerSwap.swap(q, 0, address(this), ""); assertEq(t2.balanceOf(address(this)), q + prevBal); assertGe(getHolderNAV(), origNAV); diff --git a/test/MaglevTestBase.t.sol b/test/EulerSwapTestBase.t.sol similarity index 78% rename from test/MaglevTestBase.t.sol rename to test/EulerSwapTestBase.t.sol index a77d5c4..f6936f7 100644 --- a/test/MaglevTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -1,28 +1,25 @@ // SPDX-License-Identifier: GPL-2.0-or-later - pragma solidity ^0.8.24; import {Test, console} from "forge-std/Test.sol"; - import {EVaultTestBase, TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; +import {EulerSwap} from "../src/EulerSwap.sol"; +import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; -import {Maglev} from "../src/Maglev.sol"; -import {MaglevPeriphery} from "../src/MaglevPeriphery.sol"; - -contract MaglevTestBase is EVaultTestBase { +contract EulerSwapTestBase is EVaultTestBase { address public depositor = makeAddr("depositor"); address public creator = makeAddr("creator"); address public holder = makeAddr("holder"); address public recipient = makeAddr("recipient"); address public anyone = makeAddr("anyone"); - MaglevPeriphery public periphery; + EulerSwapPeriphery public periphery; function setUp() public virtual override { super.setUp(); - periphery = new MaglevPeriphery(address(evc)); + periphery = new EulerSwapPeriphery(address(evc)); // Vault config @@ -48,12 +45,33 @@ contract MaglevTestBase is EVaultTestBase { _mintAndDeposit(holder, eTST2, 10e18); } - function getMaglevParams(uint112 debtLimitA, uint112 debtLimitB, uint256 fee) + function createEulerSwap( + uint112 debtLimitA, + uint112 debtLimitB, + uint256 fee, + uint256 px, + uint256 py, + uint256 cx, + uint256 cy + ) internal returns (EulerSwap) { + vm.prank(creator); + EulerSwap eulerSwap = new EulerSwap( + getEulerSwapParams(debtLimitA, debtLimitB, fee), + EulerSwap.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) + ); + + vm.prank(holder); + evc.setAccountOperator(holder, address(eulerSwap), true); + + return eulerSwap; + } + + function getEulerSwapParams(uint112 debtLimitA, uint112 debtLimitB, uint256 fee) internal view - returns (Maglev.Params memory) + returns (EulerSwap.Params memory) { - return Maglev.Params({ + return EulerSwap.Params({ evc: address(evc), vault0: address(eTST), vault1: address(eTST2), @@ -96,7 +114,7 @@ contract MaglevTestBase is EVaultTestBase { } function logState(address ml) internal view { - (uint112 reserve0, uint112 reserve1,) = Maglev(ml).getReserves(); + (uint112 reserve0, uint112 reserve1,) = EulerSwap(ml).getReserves(); console.log("--------------------"); console.log("Account States:"); @@ -109,7 +127,7 @@ contract MaglevTestBase is EVaultTestBase { console.log(" reserve1: ", reserve1); } - function _skimAll(Maglev ml, bool dir) internal returns (uint256) { + function _skimAll(EulerSwap ml, bool dir) internal returns (uint256) { uint256 skimmed = 0; uint256 val = 1; @@ -143,7 +161,7 @@ contract MaglevTestBase is EVaultTestBase { return skimmed; } - function skimAll(Maglev ml, bool order) public { + function skimAll(EulerSwap ml, bool order) public { if (order) { _skimAll(ml, true); _skimAll(ml, false); diff --git a/test/PreserveNav.t.sol b/test/PreserveNav.t.sol index 69da5e4..dda6fd2 100644 --- a/test/PreserveNav.t.sol +++ b/test/PreserveNav.t.sol @@ -1,41 +1,15 @@ // SPDX-License-Identifier: GPL-2.0-or-later - pragma solidity ^0.8.24; -import {Test, console} from "forge-std/Test.sol"; - -import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; -import {IEVault} from "evk/EVault/IEVault.sol"; -import {MaglevTestBase} from "./MaglevTestBase.t.sol"; +import {EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; -import {Maglev} from "../src/Maglev.sol"; - -contract PreserveNav is MaglevTestBase { - Maglev public maglev; +contract PreserveNav is EulerSwapTestBase { + EulerSwap public eulerSwap; function setUp() public virtual override { super.setUp(); } - function createMaglev( - uint112 debtLimitA, - uint112 debtLimitB, - uint256 fee, - uint256 px, - uint256 py, - uint256 cx, - uint256 cy - ) internal { - vm.prank(creator); - maglev = new Maglev( - getMaglevParams(debtLimitA, debtLimitB, fee), - Maglev.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) - ); - - vm.prank(holder); - evc.setAccountOperator(holder, address(maglev), true); - } - function test_preserve_nav( uint256 cx, uint256 cy, @@ -56,9 +30,9 @@ contract PreserveNav is MaglevTestBase { else fee -= 0.1e18; - createMaglev(50e18, 50e18, fee, 1e18, 1e18, cx, cy); + eulerSwap = createEulerSwap(50e18, 50e18, fee, 1e18, 1e18, cx, cy); - skimAll(maglev, preSkimDir); + skimAll(eulerSwap, preSkimDir); int256 nav1 = getHolderNAV(); { @@ -67,20 +41,20 @@ contract PreserveNav is MaglevTestBase { if (dir1) (t1, t2) = (assetTST, assetTST2); else (t1, t2) = (assetTST2, assetTST); - uint256 q = periphery.quoteExactInput(address(maglev), address(t1), address(t2), amount1); + uint256 q = periphery.quoteExactInput(address(eulerSwap), address(t1), address(t2), amount1); t1.mint(address(this), amount1); - t1.transfer(address(maglev), amount1); + t1.transfer(address(eulerSwap), amount1); { uint256 qPlus = q + 1; vm.expectRevert(); - if (dir1) maglev.swap(0, qPlus, address(this), ""); - else maglev.swap(qPlus, 0, address(this), ""); + if (dir1) eulerSwap.swap(0, qPlus, address(this), ""); + else eulerSwap.swap(qPlus, 0, address(this), ""); } - if (dir1) maglev.swap(0, q, address(this), ""); - else maglev.swap(q, 0, address(this), ""); + if (dir1) eulerSwap.swap(0, q, address(this), ""); + else eulerSwap.swap(q, 0, address(this), ""); } assertGe(getHolderNAV(), nav1); @@ -91,20 +65,20 @@ contract PreserveNav is MaglevTestBase { if (dir2) (t1, t2) = (assetTST, assetTST2); else (t1, t2) = (assetTST2, assetTST); - uint256 q = periphery.quoteExactInput(address(maglev), address(t1), address(t2), amount2); + uint256 q = periphery.quoteExactInput(address(eulerSwap), address(t1), address(t2), amount2); t1.mint(address(this), amount2); - t1.transfer(address(maglev), amount2); + t1.transfer(address(eulerSwap), amount2); { uint256 qPlus = q + 1; vm.expectRevert(); - if (dir2) maglev.swap(0, qPlus, address(this), ""); - else maglev.swap(qPlus, 0, address(this), ""); + if (dir2) eulerSwap.swap(0, qPlus, address(this), ""); + else eulerSwap.swap(qPlus, 0, address(this), ""); } - if (dir2) maglev.swap(0, q, address(this), ""); - else maglev.swap(q, 0, address(this), ""); + if (dir2) eulerSwap.swap(0, q, address(this), ""); + else eulerSwap.swap(q, 0, address(this), ""); } assertGe(getHolderNAV(), nav1); diff --git a/test/UniswapV2Call.t.sol b/test/UniswapV2Call.t.sol index e103eda..64bdd69 100644 --- a/test/UniswapV2Call.t.sol +++ b/test/UniswapV2Call.t.sol @@ -2,52 +2,32 @@ pragma solidity ^0.8.24; import {IUniswapV2Callee} from "../src/interfaces/IUniswapV2Callee.sol"; -// import {Test, console} from "forge-std/Test.sol"; -import {MaglevTestBase} from "./MaglevTestBase.t.sol"; -import {Maglev} from "../src/Maglev.sol"; +import {IEVault, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; -contract UniswapV2CallTest is MaglevTestBase { - Maglev public maglev; +contract UniswapV2CallTest is EulerSwapTestBase { + EulerSwap public eulerSwap; SwapCallbackTest swapCallback; function setUp() public virtual override { super.setUp(); - createMaglev(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); swapCallback = new SwapCallbackTest(); } - function createMaglev( - uint112 debtLimitA, - uint112 debtLimitB, - uint256 fee, - uint256 px, - uint256 py, - uint256 cx, - uint256 cy - ) internal { - vm.prank(creator); - maglev = new Maglev( - getMaglevParams(debtLimitA, debtLimitB, fee), - Maglev.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) - ); - - vm.prank(holder); - evc.setAccountOperator(holder, address(maglev), true); - } - function test_callback() public { uint256 amountIn = 1e18; - uint256 amountOut = periphery.quoteExactInput(address(maglev), address(assetTST), address(assetTST2), amountIn); + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); assertApproxEqAbs(amountOut, 0.9974e18, 0.0001e18); assetTST.mint(address(this), amountIn); - assetTST.transfer(address(maglev), amountIn); + assetTST.transfer(address(eulerSwap), amountIn); uint256 randomBalance = 3e18; vm.prank(anyone); - swapCallback.executeSwap(maglev, 0, amountOut, abi.encode(randomBalance)); + swapCallback.executeSwap(eulerSwap, 0, amountOut, abi.encode(randomBalance)); assertEq(assetTST2.balanceOf(address(swapCallback)), amountOut); assertEq(swapCallback.callbackSender(), address(swapCallback)); assertEq(swapCallback.callbackAmount0(), 0); @@ -62,8 +42,8 @@ contract SwapCallbackTest is IUniswapV2Callee { uint256 public callbackAmount1; uint256 public randomBalance; - function executeSwap(Maglev maglev, uint256 amountIn, uint256 amountOut, bytes calldata data) external { - maglev.swap(amountIn, amountOut, address(this), data); + function executeSwap(EulerSwap eulerSwap, uint256 amountIn, uint256 amountOut, bytes calldata data) external { + eulerSwap.swap(amountIn, amountOut, address(this), data); } function uniswapV2Call(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external { From 06b55c32afd4a391aac56794d465ed5a7ef3018e Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Sun, 16 Feb 2025 16:55:22 +0100 Subject: [PATCH 118/312] chore: re-order contracts --- src/EulerSwap.sol | 137 +++++++++++++++++------------------ test/EulerSwapTestBase.t.sol | 128 ++++++++++++++++---------------- 2 files changed, 131 insertions(+), 134 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 6b0556f..c47f120 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -8,6 +8,23 @@ import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; import {EVCUtil} from "evc/utils/EVCUtil.sol"; contract EulerSwap is IEulerSwap, EVCUtil { + struct Params { + address evc; + address vault0; + address vault1; + address myAccount; + uint112 debtLimit0; + uint112 debtLimit1; + uint256 fee; + } + + struct CurveParams { + uint256 priceX; + uint256 priceY; + uint256 concentrationX; + uint256 concentrationY; + } + bytes32 public constant curve = keccak256("EulerSwap v1"); address public immutable vault0; @@ -30,15 +47,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { uint112 public reserve1; uint32 public status; // 0 = unactivated, 1 = unlocked, 2 = locked - error Locked(); - error Overflow(); - error BadFee(); - error DifferentEVC(); - error AssetsOutOfOrderOrEqual(); - error CurveViolation(); - event EulerSwapCreated(address indexed eulerSwap, address indexed asset0, address indexed asset1); - event Swap( address indexed sender, uint256 amount0In, @@ -50,6 +59,13 @@ contract EulerSwap is IEulerSwap, EVCUtil { address indexed to ); + error Locked(); + error Overflow(); + error BadFee(); + error DifferentEVC(); + error AssetsOutOfOrderOrEqual(); + error CurveViolation(); + modifier nonReentrant() { if (status == 0) activate(); require(status == 1, Locked()); @@ -58,23 +74,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { status = 1; } - struct Params { - address evc; - address vault0; - address vault1; - address myAccount; - uint112 debtLimit0; - uint112 debtLimit1; - uint256 fee; - } - - struct CurveParams { - uint256 priceX; - uint256 priceY; - uint256 concentrationX; - uint256 concentrationY; - } - constructor(Params memory params, CurveParams memory curveParams) EVCUtil(params.evc) { // EulerSwap params @@ -109,34 +108,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { emit EulerSwapCreated(address(this), asset0Addr, asset1Addr); } - /// @inheritdoc IEulerSwap - function activate() public { - require(status != 2, Locked()); - status = 1; - - IERC20(asset0).approve(vault0, type(uint256).max); - IERC20(asset1).approve(vault1, type(uint256).max); - - IEVC(evc).enableCollateral(myAccount, vault0); - IEVC(evc).enableCollateral(myAccount, vault1); - } - - /// @dev EulerSwap curve definition - function f(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { - return y0 + px * 1e18 / py * (c * (2 * x0 - xt) / 1e18 + (1e18 - c) * x0 / 1e18 * x0 / xt - x0) / 1e18; - } - - /// @inheritdoc IEulerSwap - function verify(uint256 newReserve0, uint256 newReserve1) public view returns (bool) { - if (newReserve0 >= initialReserve0) { - if (newReserve1 >= initialReserve1) return true; - return newReserve0 >= f(newReserve1, priceY, priceX, initialReserve1, initialReserve0, concentrationY); - } else { - if (newReserve1 < initialReserve1) return false; - return newReserve1 >= f(newReserve0, priceX, priceY, initialReserve0, initialReserve1, concentrationX); - } - } - /// @inheritdoc IEulerSwap function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external @@ -188,29 +159,27 @@ contract EulerSwap is IEulerSwap, EVCUtil { return (reserve0, reserve1, status); } - // Internal utilities + /// @inheritdoc IEulerSwap + function activate() public { + require(status != 2, Locked()); + status = 1; - function myDebt(address vault) internal view returns (uint256) { - return IEVault(vault).debtOf(myAccount); - } + IERC20(asset0).approve(vault0, type(uint256).max); + IERC20(asset1).approve(vault1, type(uint256).max); - function myBalance(address vault) internal view returns (uint256) { - uint256 shares = IEVault(vault).balanceOf(myAccount); - return shares == 0 ? 0 : IEVault(vault).convertToAssets(shares); + IEVC(evc).enableCollateral(myAccount, vault0); + IEVC(evc).enableCollateral(myAccount, vault1); } - function offsetReserve(uint112 reserve, address vault) internal view returns (uint112) { - uint256 offset; - uint256 debt = myDebt(vault); - - if (debt != 0) { - offset = reserve > debt ? reserve - debt : 0; + /// @inheritdoc IEulerSwap + function verify(uint256 newReserve0, uint256 newReserve1) public view returns (bool) { + if (newReserve0 >= initialReserve0) { + if (newReserve1 >= initialReserve1) return true; + return newReserve0 >= f(newReserve1, priceY, priceX, initialReserve1, initialReserve0, concentrationY); } else { - offset = reserve + myBalance(vault); + if (newReserve1 < initialReserve1) return false; + return newReserve1 >= f(newReserve0, priceX, priceY, initialReserve0, initialReserve1, concentrationX); } - - require(offset <= type(uint112).max, Overflow()); - return uint112(offset); } function withdrawAssets(address vault, uint256 amount, address to) internal { @@ -243,4 +212,32 @@ contract EulerSwap is IEulerSwap, EVCUtil { } } } + + function myDebt(address vault) internal view returns (uint256) { + return IEVault(vault).debtOf(myAccount); + } + + function myBalance(address vault) internal view returns (uint256) { + uint256 shares = IEVault(vault).balanceOf(myAccount); + return shares == 0 ? 0 : IEVault(vault).convertToAssets(shares); + } + + function offsetReserve(uint112 reserve, address vault) internal view returns (uint112) { + uint256 offset; + uint256 debt = myDebt(vault); + + if (debt != 0) { + offset = reserve > debt ? reserve - debt : 0; + } else { + offset = reserve + myBalance(vault); + } + + require(offset <= type(uint112).max, Overflow()); + return uint112(offset); + } + + /// @dev EulerSwap curve definition + function f(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { + return y0 + px * 1e18 / py * (c * (2 * x0 - xt) / 1e18 + (1e18 - c) * x0 / 1e18 * x0 / xt - x0) / 1e18; + } } diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index f6936f7..eb13977 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -16,6 +16,12 @@ contract EulerSwapTestBase is EVaultTestBase { EulerSwapPeriphery public periphery; + modifier monotonicHolderNAV() { + int256 orig = getHolderNAV(); + _; + assertGe(getHolderNAV(), orig); + } + function setUp() public virtual override { super.setUp(); @@ -38,11 +44,35 @@ contract EulerSwapTestBase is EVaultTestBase { // Funding - _mintAndDeposit(depositor, eTST, 100e18); - _mintAndDeposit(depositor, eTST2, 100e18); + mintAndDeposit(depositor, eTST, 100e18); + mintAndDeposit(depositor, eTST2, 100e18); + + mintAndDeposit(holder, eTST, 10e18); + mintAndDeposit(holder, eTST2, 10e18); + } - _mintAndDeposit(holder, eTST, 10e18); - _mintAndDeposit(holder, eTST2, 10e18); + function skimAll(EulerSwap ml, bool order) public { + if (order) { + runSkimAll(ml, true); + runSkimAll(ml, false); + } else { + runSkimAll(ml, false); + runSkimAll(ml, true); + } + } + + 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)); + 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); } function createEulerSwap( @@ -66,23 +96,7 @@ contract EulerSwapTestBase is EVaultTestBase { return eulerSwap; } - function getEulerSwapParams(uint112 debtLimitA, uint112 debtLimitB, uint256 fee) - internal - view - returns (EulerSwap.Params memory) - { - return EulerSwap.Params({ - evc: address(evc), - vault0: address(eTST), - vault1: address(eTST2), - myAccount: holder, - debtLimit0: debtLimitA, - debtLimit1: debtLimitB, - fee: fee - }); - } - - function _mintAndDeposit(address who, IEVault vault, uint256 amount) internal { + function mintAndDeposit(address who, IEVault vault, uint256 amount) internal { TestERC20 tok = TestERC20(vault.asset()); tok.mint(who, amount); @@ -93,41 +107,7 @@ contract EulerSwapTestBase is EVaultTestBase { vault.deposit(amount, who); } - 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); - } - - modifier monotonicHolderNAV() { - int256 orig = getHolderNAV(); - _; - assertGe(getHolderNAV(), orig); - } - - function logState(address ml) internal view { - (uint112 reserve0, uint112 reserve1,) = EulerSwap(ml).getReserves(); - - console.log("--------------------"); - console.log("Account States:"); - console.log("HOLDER"); - console.log(" eTST Vault assets: ", eTST.convertToAssets(eTST.balanceOf(holder))); - console.log(" eTST Vault debt: ", eTST.debtOf(holder)); - console.log(" eTST2 Vault assets: ", eTST2.convertToAssets(eTST2.balanceOf(holder))); - console.log(" eTST2 Vault debt: ", eTST2.debtOf(holder)); - console.log(" reserve0: ", reserve0); - console.log(" reserve1: ", reserve1); - } - - function _skimAll(EulerSwap ml, bool dir) internal returns (uint256) { + function runSkimAll(EulerSwap ml, bool dir) internal returns (uint256) { uint256 skimmed = 0; uint256 val = 1; @@ -161,13 +141,33 @@ contract EulerSwapTestBase is EVaultTestBase { return skimmed; } - function skimAll(EulerSwap ml, bool order) public { - if (order) { - _skimAll(ml, true); - _skimAll(ml, false); - } else { - _skimAll(ml, false); - _skimAll(ml, true); - } + function getEulerSwapParams(uint112 debtLimitA, uint112 debtLimitB, uint256 fee) + internal + view + returns (EulerSwap.Params memory) + { + return EulerSwap.Params({ + evc: address(evc), + vault0: address(eTST), + vault1: address(eTST2), + myAccount: holder, + debtLimit0: debtLimitA, + debtLimit1: debtLimitB, + fee: fee + }); + } + + function logState(address ml) internal view { + (uint112 reserve0, uint112 reserve1,) = EulerSwap(ml).getReserves(); + + console.log("--------------------"); + console.log("Account States:"); + console.log("HOLDER"); + console.log(" eTST Vault assets: ", eTST.convertToAssets(eTST.balanceOf(holder))); + console.log(" eTST Vault debt: ", eTST.debtOf(holder)); + console.log(" eTST2 Vault assets: ", eTST2.convertToAssets(eTST2.balanceOf(holder))); + console.log(" eTST2 Vault debt: ", eTST2.debtOf(holder)); + console.log(" reserve0: ", reserve0); + console.log(" reserve1: ", reserve1); } } From 4eabe4734b8a5221a35721dc2737900167665a64 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Sun, 16 Feb 2025 16:57:32 +0100 Subject: [PATCH 119/312] update architecture doc --- docs/architecture.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 11ebe01..424853c 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -51,9 +51,9 @@ The EulerSwap contract tracks what it believes the reserves to be by caching the ### **1. Core contracts** -#### **Maglev contract** +#### **EulerSwap contract** -The `Maglev` contract is the core of EulerSwap and is responsible for: +The `EulerSwap` contract is the core of EulerSwap and is responsible for: - Managing liquidity reserves. - Executing token swaps based on the EulerSwap curve. @@ -76,9 +76,9 @@ The `Maglev` contract is the core of EulerSwap and is responsible for: ### **2. Periphery contracts** -#### **MaglevPeriphery contract** +#### **EulerSwapPeriphery contract** -The `MaglevPeriphery` contract extends the functionality of the core Maglev contract by providing: +The `EulerSwapPeriphery` contract extends the functionality of the core EulerSwap contract by providing: - **Swap price quotations** before execution. - **Liquidity checks** to ensure solvency before transactions. @@ -86,10 +86,10 @@ The `MaglevPeriphery` contract extends the functionality of the core Maglev cont ##### **Key functions** -- `quoteExactInput(address maglev, address tokenIn, address tokenOut, uint256 amountIn)`: Estimates the output amount for a given input. -- `quoteExactOutput(address maglev, address tokenIn, address tokenOut, uint256 amountOut)`: Estimates the required input amount to receive a specified output. -- `computeQuote(IMaglev maglev, address tokenIn, address tokenOut, uint256 amount, bool exactIn)`: A high-level function to compute swaps while enforcing fee multipliers. -- `binarySearch(IMaglev maglev, uint112 reserve0, uint112 reserve1, uint256 amount, bool exactIn, bool asset0IsInput)`: Uses binary search to determine an optimal swap amount along the curve. +- `quoteExactInput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn)`: Estimates the output amount for a given input. +- `quoteExactOutput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut)`: Estimates the required input amount to receive a specified output. +- `computeQuote(IEulerSwap eulerSwap, address tokenIn, address tokenOut, uint256 amount, bool exactIn)`: A high-level function to compute swaps while enforcing fee multipliers. +- `binarySearch(IEulerSwap eulerSwap, uint112 reserve0, uint112 reserve1, uint256 amount, bool exactIn, bool asset0IsInput)`: Uses binary search to determine an optimal swap amount along the curve. ### **3. Vault integration** @@ -110,8 +110,8 @@ EulerSwap integrates with **Ethereum Vault Connector (EVC)** to enable collatera EulerSwap’s architecture is designed for **efficient, secure, and collateral-backed trading** with a custom **swapping curve**. The system leverages: -- **Maglev** as the core AMM contract. -- **MaglevPeriphery** for auxiliary quoting and validations. +- **EulerSwap** as the core AMM contract. +- **EulerSwapPeriphery** for auxiliary quoting and validations. - **Ethereum Vault Connector (EVC)** for collateralized vault management. - **Security-focused design** to prevent vulnerabilities in asset handling. From a54cf8efbe0af15ff1c90779f5bf20ecfeb88a49 Mon Sep 17 00:00:00 2001 From: kasperpawlowski Date: Sun, 16 Feb 2025 21:09:13 +0000 Subject: [PATCH 120/312] feat: replace debtOf with isControllerEnabled --- src/EulerSwap.sol | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index c47f120..5f33c6a 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -200,14 +200,12 @@ contract EulerSwap is IEulerSwap, EVCUtil { function depositAssets(address vault, uint256 amount) internal { IEVault(vault).deposit(amount, myAccount); - uint256 debt = myDebt(vault); - - if (debt > 0) { + if (IEVC(evc).isControllerEnabled(myAccount, vault)) { IEVC(evc).call( vault, myAccount, 0, abi.encodeCall(IBorrowing.repayWithShares, (type(uint256).max, myAccount)) ); - if (myDebt(vault) == 0) { + if (IEVault(vault).debtOf(myAccount) == 0) { IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IRiskManager.disableController, ())); } } From 80daa1fda2a927bc59b994d480bd15fedc2c3e5f Mon Sep 17 00:00:00 2001 From: kasperpawlowski Date: Sun, 16 Feb 2025 21:21:38 +0000 Subject: [PATCH 121/312] feat: permit2 support --- remappings.txt | 1 + src/EulerSwap.sol | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/remappings.txt b/remappings.txt index 5e34eeb..56ee1ca 100644 --- a/remappings.txt +++ b/remappings.txt @@ -3,3 +3,4 @@ evc/=lib/ethereum-vault-connector/src/ evk/=lib/euler-vault-kit/src/ ethereum-vault-connector/=lib/ethereum-vault-connector/src/ evk-test/=lib/euler-vault-kit/test/ +permit2/=lib/euler-vault-kit/lib/permit2/ \ No newline at end of file diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 5f33c6a..7b2d58e 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -5,6 +5,7 @@ import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault, IERC20, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; import {IUniswapV2Callee} from "./interfaces/IUniswapV2Callee.sol"; import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; +import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; import {EVCUtil} from "evc/utils/EVCUtil.sol"; contract EulerSwap is IEulerSwap, EVCUtil { @@ -164,8 +165,21 @@ contract EulerSwap is IEulerSwap, EVCUtil { require(status != 2, Locked()); status = 1; - IERC20(asset0).approve(vault0, type(uint256).max); - IERC20(asset1).approve(vault1, type(uint256).max); + address permit2 = IEVault(vault0).permit2Address(); + if (permit2 == address(0)) { + IERC20(asset0).approve(vault0, type(uint256).max); + } else { + IERC20(asset0).approve(permit2, type(uint256).max); + IAllowanceTransfer(permit2).approve(asset0, vault0, type(uint160).max, type(uint48).max); + } + + permit2 = IEVault(vault1).permit2Address(); + if (permit2 == address(0)) { + IERC20(asset1).approve(vault1, type(uint256).max); + } else { + IERC20(asset1).approve(permit2, type(uint256).max); + IAllowanceTransfer(permit2).approve(asset1, vault1, type(uint160).max, type(uint48).max); + } IEVC(evc).enableCollateral(myAccount, vault0); IEVC(evc).enableCollateral(myAccount, vault1); From 0bd1b12ff5669d676a94be8fa1c1be92c5156b82 Mon Sep 17 00:00:00 2001 From: kasperpawlowski Date: Sun, 16 Feb 2025 21:25:04 +0000 Subject: [PATCH 122/312] fix: remove redundant constructor parameter --- src/EulerSwap.sol | 8 ++------ test/EulerSwapTest.t.sol | 17 ----------------- test/EulerSwapTestBase.t.sol | 1 - 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 7b2d58e..316f116 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -10,7 +10,6 @@ import {EVCUtil} from "evc/utils/EVCUtil.sol"; contract EulerSwap is IEulerSwap, EVCUtil { struct Params { - address evc; address vault0; address vault1; address myAccount; @@ -75,14 +74,11 @@ contract EulerSwap is IEulerSwap, EVCUtil { status = 1; } - constructor(Params memory params, CurveParams memory curveParams) EVCUtil(params.evc) { + constructor(Params memory params, CurveParams memory curveParams) EVCUtil(IEVault(params.vault0).EVC()) { // EulerSwap params require(params.fee < 1e18, BadFee()); - - address vault0Evc = IEVault(params.vault0).EVC(); - require(vault0Evc == IEVault(params.vault1).EVC(), DifferentEVC()); - require(vault0Evc == params.evc, DifferentEVC()); + require(IEVault(params.vault0).EVC() == IEVault(params.vault1).EVC(), DifferentEVC()); address asset0Addr = IEVault(params.vault0).asset(); address asset1Addr = IEVault(params.vault1).asset(); diff --git a/test/EulerSwapTest.t.sol b/test/EulerSwapTest.t.sol index d81e85f..a690af5 100644 --- a/test/EulerSwapTest.t.sol +++ b/test/EulerSwapTest.t.sol @@ -12,23 +12,6 @@ contract EulerSwapTest is EulerSwapTestBase { eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); } - function test_different_EVC() public { - vm.expectRevert(EulerSwap.DifferentEVC.selector); - - new EulerSwap( - EulerSwap.Params({ - evc: address(makeAddr("RANDOM_EVC")), - vault0: address(eTST), - vault1: address(eTST2), - myAccount: holder, - debtLimit0: 50e18, - debtLimit1: 50e18, - fee: 0 - }), - EulerSwap.CurveParams({priceX: 1e18, priceY: 1e18, concentrationX: 4e18, concentrationY: 0.85e18}) - ); - } - function test_basicSwap_exactIn() public monotonicHolderNAV { uint256 amountIn = 1e18; uint256 amountOut = diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index eb13977..3deb004 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -147,7 +147,6 @@ contract EulerSwapTestBase is EVaultTestBase { returns (EulerSwap.Params memory) { return EulerSwap.Params({ - evc: address(evc), vault0: address(eTST), vault1: address(eTST2), myAccount: holder, From c1eb29632d7022eba9de304256b81d78f04c4360 Mon Sep 17 00:00:00 2001 From: kasperpawlowski Date: Sun, 16 Feb 2025 21:27:40 +0000 Subject: [PATCH 123/312] fix: restore previous implementation --- src/EulerSwap.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 316f116..698faf1 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -215,7 +215,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { vault, myAccount, 0, abi.encodeCall(IBorrowing.repayWithShares, (type(uint256).max, myAccount)) ); - if (IEVault(vault).debtOf(myAccount) == 0) { + if (myDebt(vault) == 0) { IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IRiskManager.disableController, ())); } } From 651f1e28837dec290090ab400e8f0290dd140e91 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 17 Feb 2025 11:31:59 +0100 Subject: [PATCH 124/312] factory --- src/EulerSwap.sol | 17 ---- ...erSwapFactory.sol => EulerSwapFactory.sol} | 97 +++++++++++-------- src/interfaces/IEulerSwap.sol | 17 ++++ ...rSwapFactory.sol => IEulerSwapFactory.sol} | 28 +++--- test/EulerSwapFactoryTest.t.sol | 79 +++++++++++++++ test/EulerSwapTest.t.sol | 6 +- test/EulerSwapTestBase.t.sol | 6 +- test/MaglevEulerSwapFactoryTest.t.sol | 75 -------------- 8 files changed, 172 insertions(+), 153 deletions(-) rename src/{MaglevEulerSwapFactory.sol => EulerSwapFactory.sol} (52%) rename src/interfaces/{IMaglevEulerSwapFactory.sol => IEulerSwapFactory.sol} (51%) create mode 100644 test/EulerSwapFactoryTest.t.sol delete mode 100644 test/MaglevEulerSwapFactoryTest.t.sol diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index c47f120..5b7f413 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -8,23 +8,6 @@ import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; import {EVCUtil} from "evc/utils/EVCUtil.sol"; contract EulerSwap is IEulerSwap, EVCUtil { - struct Params { - address evc; - address vault0; - address vault1; - address myAccount; - uint112 debtLimit0; - uint112 debtLimit1; - uint256 fee; - } - - struct CurveParams { - uint256 priceX; - uint256 priceY; - uint256 concentrationX; - uint256 concentrationY; - } - bytes32 public constant curve = keccak256("EulerSwap v1"); address public immutable vault0; diff --git a/src/MaglevEulerSwapFactory.sol b/src/EulerSwapFactory.sol similarity index 52% rename from src/MaglevEulerSwapFactory.sol rename to src/EulerSwapFactory.sol index b2b1be6..3c9b27b 100644 --- a/src/MaglevEulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -1,77 +1,90 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; -import {IMaglevEulerSwapFactory} from "./interfaces/IMaglevEulerSwapFactory.sol"; +import {IEulerSwapFactory} from "./interfaces/IEulerSwapFactory.sol"; +import {IEulerSwap, EulerSwap} from "./EulerSwap.sol"; import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; -import {MaglevEulerSwap as Maglev, MaglevBase} from "./MaglevEulerSwap.sol"; -/// @title MaglevEulerSwapRegistry contract +/// @title EulerSwapFactory contract /// @custom:security-contact security@euler.xyz /// @author Euler Labs (https://www.eulerlabs.com/) -contract MaglevEulerSwapFactory is IMaglevEulerSwapFactory, Ownable { - event PoolDeployed(address indexed asset0, address indexed asset1, uint256 indexed feeMultiplier, address pool); - - error InvalidQuery(); - +contract EulerSwapFactory is IEulerSwapFactory, Ownable { /// @dev EVC address. address public immutable evc; /// @dev An array to store all pools addresses. address[] public allPools; - /// @dev Mapping from asset0/asset1/fee => pool address. - mapping(bytes32 => address) public getPool; + /// @dev Mapping to store pool addresses + mapping(bytes32 poolKey => address pool) public getPool; + + event PoolDeployed( + address indexed asset0, + address indexed asset1, + uint256 indexed feeMultiplier, + address swapAccount, + uint256 priceX, + uint256 priceY, + uint256 concentrationX, + uint256 concentrationY, + address pool + ); + + error InvalidQuery(); constructor(address evcAddr) Ownable(msg.sender) { evc = evcAddr; } /// @notice Deploy EulerSwap pool. - function deployPool( - address vault0, - address vault1, - address holder, - uint256 fee, - uint256 priceX, - uint256 priceY, - uint256 concentrationX, - uint256 concentrationY, - uint112 debtLimit0, - uint112 debtLimit1 - ) external onlyOwner returns (address) { - Maglev pool = new Maglev( - MaglevBase.BaseParams({ + function deployPool(DeployParams memory params) external returns (address) { + EulerSwap pool = new EulerSwap( + IEulerSwap.Params({ evc: address(evc), - vault0: vault0, - vault1: vault1, - myAccount: holder, - debtLimit0: debtLimit0, - debtLimit1: debtLimit1, - fee: fee + vault0: params.vault0, + vault1: params.vault1, + myAccount: params.holder, + debtLimit0: params.debtLimit0, + debtLimit1: params.debtLimit1, + fee: params.fee }), - Maglev.EulerSwapParams({ - priceX: priceX, - priceY: priceY, - concentrationX: concentrationX, - concentrationY: concentrationY + IEulerSwap.CurveParams({ + priceX: params.priceX, + priceY: params.priceY, + concentrationX: params.concentrationX, + concentrationY: params.concentrationY }) ); address poolAsset0 = pool.asset0(); address poolAsset1 = pool.asset1(); uint256 feeMultiplier = pool.feeMultiplier(); - address myAccount = pool.myAccount(); - uint256 priceX = pool.priceX(); - uint256 priceY = pool.priceY(); - uint256 concentrationX = pool.concentrationX(); - uint256 concentrationY = pool.concentrationY(); bytes32 poolKey = keccak256( - abi.encode(poolAsset0, poolAsset1, feeMultiplier, myAccount, priceX, priceY, concentrationX, concentrationY) + abi.encode( + poolAsset0, + poolAsset1, + feeMultiplier, + params.holder, + params.priceX, + params.priceY, + params.concentrationX, + params.concentrationY + ) ); getPool[poolKey] = address(pool); allPools.push(address(pool)); - emit PoolDeployed(poolAsset0, poolAsset1, feeMultiplier, address(pool)); + emit PoolDeployed( + poolAsset0, + poolAsset1, + feeMultiplier, + params.holder, + params.priceX, + params.priceY, + params.concentrationX, + params.concentrationY, + address(pool) + ); return address(pool); } diff --git a/src/interfaces/IEulerSwap.sol b/src/interfaces/IEulerSwap.sol index c9a9865..d533faf 100644 --- a/src/interfaces/IEulerSwap.sol +++ b/src/interfaces/IEulerSwap.sol @@ -2,6 +2,23 @@ pragma solidity >=0.8.0; interface IEulerSwap { + struct Params { + address evc; + address vault0; + address vault1; + address myAccount; + uint112 debtLimit0; + uint112 debtLimit1; + uint256 fee; + } + + struct CurveParams { + uint256 priceX; + uint256 priceY; + uint256 concentrationX; + uint256 concentrationY; + } + /// @notice Optimistically sends the requested amounts of tokens to the `to` /// address, invokes `uniswapV2Call` callback on `to` (if `data` was provided), /// and then verifies that a sufficient amount of tokens were transferred to diff --git a/src/interfaces/IMaglevEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol similarity index 51% rename from src/interfaces/IMaglevEulerSwapFactory.sol rename to src/interfaces/IEulerSwapFactory.sol index 6017c10..00e2b97 100644 --- a/src/interfaces/IMaglevEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -1,19 +1,21 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.0; -interface IMaglevEulerSwapFactory { - function deployPool( - address vault0, - address vault1, - address holder, - uint256 fee, - uint256 priceX, - uint256 priceY, - uint256 concentrationX, - uint256 concentrationY, - uint112 debtLimit0, - uint112 debtLimit1 - ) external returns (address); +interface IEulerSwapFactory { + struct DeployParams { + address vault0; + address vault1; + address holder; + uint256 fee; + uint256 priceX; + uint256 priceY; + uint256 concentrationX; + uint256 concentrationY; + uint112 debtLimit0; + uint112 debtLimit1; + } + + function deployPool(DeployParams memory params) external returns (address); function evc() external view returns (address); function allPools(uint256 index) external view returns (address); diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol new file mode 100644 index 0000000..5ea6cf8 --- /dev/null +++ b/test/EulerSwapFactoryTest.t.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; + +import {EulerSwapTestBase, EulerSwap} from "./EulerSwapTestBase.t.sol"; +import {EulerSwapFactory, IEulerSwapFactory} from "../src/EulerSwapFactory.sol"; + +contract EulerSwapFactoryTest is EulerSwapTestBase { + EulerSwapFactory public eulerSwapFactory; + + uint256 minFee = 0.0000000000001e18; + + function setUp() public virtual override { + super.setUp(); + + vm.prank(creator); + eulerSwapFactory = new EulerSwapFactory(address(evc)); + } + + function testDeployPool() public { + uint256 allPoolsLengthBefore = eulerSwapFactory.allPoolsLength(); + + vm.prank(creator); + EulerSwap eulerSwap = EulerSwap( + eulerSwapFactory.deployPool( + IEulerSwapFactory.DeployParams( + address(eTST), address(eTST2), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 + ) + ) + ); + + uint256 allPoolsLengthAfter = eulerSwapFactory.allPoolsLength(); + bytes32 poolKey = keccak256( + abi.encode( + eulerSwap.asset0(), + eulerSwap.asset1(), + eulerSwap.feeMultiplier(), + eulerSwap.myAccount(), + eulerSwap.priceX(), + eulerSwap.priceY(), + eulerSwap.concentrationX(), + eulerSwap.concentrationY() + ) + ); + + assertEq(allPoolsLengthAfter - allPoolsLengthBefore, 1); + assertEq(eulerSwapFactory.getPool(poolKey), address(eulerSwap)); + assertEq(eulerSwapFactory.getPool(poolKey), address(eulerSwap)); + + address[] memory poolsList = eulerSwapFactory.getAllPoolsListSlice(0, type(uint256).max); + assertEq(poolsList.length, 1); + assertEq(poolsList[0], address(eulerSwap)); + assertEq(eulerSwapFactory.allPools(0), address(eulerSwap)); + } + + function testInvalidGetAllPoolsListSliceQuery() public { + vm.expectRevert(EulerSwapFactory.InvalidQuery.selector); + eulerSwapFactory.getAllPoolsListSlice(1, 0); + } + + function testDeployWithAssetsOutOfOrderOrEqual() public { + vm.prank(creator); + vm.expectRevert(EulerSwap.AssetsOutOfOrderOrEqual.selector); + eulerSwapFactory.deployPool( + IEulerSwapFactory.DeployParams( + address(eTST), address(eTST), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 + ) + ); + } + + function testDeployWithBadFee() public { + vm.prank(creator); + vm.expectRevert(EulerSwap.BadFee.selector); + eulerSwapFactory.deployPool( + IEulerSwapFactory.DeployParams( + address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 + ) + ); + } +} diff --git a/test/EulerSwapTest.t.sol b/test/EulerSwapTest.t.sol index d81e85f..9a9fb4e 100644 --- a/test/EulerSwapTest.t.sol +++ b/test/EulerSwapTest.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.24; -import {IEVault, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; +import {IEVault, IEulerSwap, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; contract EulerSwapTest is EulerSwapTestBase { EulerSwap public eulerSwap; @@ -16,7 +16,7 @@ contract EulerSwapTest is EulerSwapTestBase { vm.expectRevert(EulerSwap.DifferentEVC.selector); new EulerSwap( - EulerSwap.Params({ + IEulerSwap.Params({ evc: address(makeAddr("RANDOM_EVC")), vault0: address(eTST), vault1: address(eTST2), @@ -25,7 +25,7 @@ contract EulerSwapTest is EulerSwapTestBase { debtLimit1: 50e18, fee: 0 }), - EulerSwap.CurveParams({priceX: 1e18, priceY: 1e18, concentrationX: 4e18, concentrationY: 0.85e18}) + IEulerSwap.CurveParams({priceX: 1e18, priceY: 1e18, concentrationX: 4e18, concentrationY: 0.85e18}) ); } diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index eb13977..94fab06 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.24; import {Test, console} from "forge-std/Test.sol"; import {EVaultTestBase, TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; -import {EulerSwap} from "../src/EulerSwap.sol"; +import {IEulerSwap, EulerSwap} from "../src/EulerSwap.sol"; import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; contract EulerSwapTestBase is EVaultTestBase { @@ -87,7 +87,7 @@ contract EulerSwapTestBase is EVaultTestBase { vm.prank(creator); EulerSwap eulerSwap = new EulerSwap( getEulerSwapParams(debtLimitA, debtLimitB, fee), - EulerSwap.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) + IEulerSwap.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) ); vm.prank(holder); @@ -146,7 +146,7 @@ contract EulerSwapTestBase is EVaultTestBase { view returns (EulerSwap.Params memory) { - return EulerSwap.Params({ + return IEulerSwap.Params({ evc: address(evc), vault0: address(eTST), vault1: address(eTST2), diff --git a/test/MaglevEulerSwapFactoryTest.t.sol b/test/MaglevEulerSwapFactoryTest.t.sol deleted file mode 100644 index 0ae6f45..0000000 --- a/test/MaglevEulerSwapFactoryTest.t.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.24; - -// import {Test, console} from "forge-std/Test.sol"; -// import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; -// import {IEVault} from "evk/EVault/IEVault.sol"; -import {MaglevTestBase} from "./MaglevTestBase.t.sol"; -import {MaglevEulerSwap as Maglev, MaglevBase} from "../src/MaglevEulerSwap.sol"; -import {MaglevEulerSwapFactory} from "../src/MaglevEulerSwapFactory.sol"; - -contract MaglevEulerSwapFactoryTest is MaglevTestBase { - MaglevEulerSwapFactory public eulerSwapFactory; - - uint256 minFee = 0.0000000000001e18; - - function setUp() public virtual override { - super.setUp(); - - vm.prank(creator); - eulerSwapFactory = new MaglevEulerSwapFactory(address(evc)); - } - - function testDeployPool() public { - uint256 allPoolsLengthBefore = eulerSwapFactory.allPoolsLength(); - - vm.prank(creator); - Maglev maglev = Maglev( - eulerSwapFactory.deployPool( - address(eTST), address(eTST2), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 - ) - ); - - uint256 allPoolsLengthAfter = eulerSwapFactory.allPoolsLength(); - bytes32 poolKey = keccak256( - abi.encode( - maglev.asset0(), - maglev.asset1(), - maglev.feeMultiplier(), - maglev.myAccount(), - maglev.priceX(), - maglev.priceY(), - maglev.concentrationX(), - maglev.concentrationY() - ) - ); - - assertEq(allPoolsLengthAfter - allPoolsLengthBefore, 1); - assertEq(eulerSwapFactory.getPool(poolKey), address(maglev)); - assertEq(eulerSwapFactory.getPool(poolKey), address(maglev)); - - address[] memory poolsList = eulerSwapFactory.getAllPoolsListSlice(0, type(uint256).max); - assertEq(poolsList.length, 1); - assertEq(poolsList[0], address(maglev)); - assertEq(eulerSwapFactory.allPools(0), address(maglev)); - } - - function testInvalidGetAllPoolsListSliceQuery() public { - vm.expectRevert(MaglevEulerSwapFactory.InvalidQuery.selector); - eulerSwapFactory.getAllPoolsListSlice(1, 0); - } - - function testDeployWithUnsupportedPair() public { - vm.prank(creator); - vm.expectRevert(MaglevBase.UnsupportedPair.selector); - eulerSwapFactory.deployPool(address(eTST), address(eTST), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18); - } - - function testDeployWithBadFee() public { - vm.prank(creator); - vm.expectRevert(MaglevBase.BadFee.selector); - eulerSwapFactory.deployPool( - address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 - ); - } -} From baeb1742d828776fa09410b7319aa2179d8db237 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 17 Feb 2025 11:33:32 +0100 Subject: [PATCH 125/312] update config --- foundry.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/foundry.toml b/foundry.toml index d8142ba..4c9b590 100644 --- a/foundry.toml +++ b/foundry.toml @@ -4,7 +4,7 @@ out = "out" libs = ["lib"] solc = "0.8.27" optimizer = true -optimizer_runs = 800 +optimizer_runs = 10000 gas_reports = ["*"] # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options From bbd8d80dc32c6e0bd7ed99d2824761c3d8b0102c Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 17 Feb 2025 15:49:38 +0100 Subject: [PATCH 126/312] fix --- src/EulerSwapFactory.sol | 1 - src/interfaces/IEulerSwap.sol | 1 - test/EulerSwapTestBase.t.sol | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 3c9b27b..0dce633 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -38,7 +38,6 @@ contract EulerSwapFactory is IEulerSwapFactory, Ownable { function deployPool(DeployParams memory params) external returns (address) { EulerSwap pool = new EulerSwap( IEulerSwap.Params({ - evc: address(evc), vault0: params.vault0, vault1: params.vault1, myAccount: params.holder, diff --git a/src/interfaces/IEulerSwap.sol b/src/interfaces/IEulerSwap.sol index d533faf..b939815 100644 --- a/src/interfaces/IEulerSwap.sol +++ b/src/interfaces/IEulerSwap.sol @@ -3,7 +3,6 @@ pragma solidity >=0.8.0; interface IEulerSwap { struct Params { - address evc; address vault0; address vault1; address myAccount; diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index 8fb1547..dce25c4 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -146,7 +146,7 @@ contract EulerSwapTestBase is EVaultTestBase { view returns (EulerSwap.Params memory) { - return EulerSwap.Params({ + return IEulerSwap.Params({ vault0: address(eTST), vault1: address(eTST2), myAccount: holder, From 9e1ab2d41b2f006397b063f1c752daba319cbc4a Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 17 Feb 2025 15:53:07 +0100 Subject: [PATCH 127/312] fix --- src/EulerSwapFactory.sol | 6 +----- src/interfaces/IEulerSwapFactory.sol | 1 - test/EulerSwapFactoryTest.t.sol | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 0dce633..7249472 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -9,8 +9,6 @@ import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; /// @custom:security-contact security@euler.xyz /// @author Euler Labs (https://www.eulerlabs.com/) contract EulerSwapFactory is IEulerSwapFactory, Ownable { - /// @dev EVC address. - address public immutable evc; /// @dev An array to store all pools addresses. address[] public allPools; /// @dev Mapping to store pool addresses @@ -30,9 +28,7 @@ contract EulerSwapFactory is IEulerSwapFactory, Ownable { error InvalidQuery(); - constructor(address evcAddr) Ownable(msg.sender) { - evc = evcAddr; - } + constructor() Ownable(msg.sender) {} /// @notice Deploy EulerSwap pool. function deployPool(DeployParams memory params) external returns (address) { diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol index 00e2b97..87746c7 100644 --- a/src/interfaces/IEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -17,7 +17,6 @@ interface IEulerSwapFactory { function deployPool(DeployParams memory params) external returns (address); - function evc() external view returns (address); function allPools(uint256 index) external view returns (address); function getPool(bytes32 poolKey) external view returns (address); function allPoolsLength() external view returns (uint256); diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index 5ea6cf8..e939056 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -13,7 +13,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { super.setUp(); vm.prank(creator); - eulerSwapFactory = new EulerSwapFactory(address(evc)); + eulerSwapFactory = new EulerSwapFactory(); } function testDeployPool() public { From 5611fa97beac4ce72c6eab5e0df4ef5d232c5053 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Tue, 18 Feb 2025 18:02:21 +0100 Subject: [PATCH 128/312] TODO --- TODO | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 0000000..88cb24a --- /dev/null +++ b/TODO @@ -0,0 +1,40 @@ +! Don't make quotes that would cause a swap to fail if supply/borrow caps exceeded +* Better revert messages when a swap fails due to maglev debt-limit/vault utilisation/etc + * currently it's an arithmetic underflow + + +TESTING + +* when exchange rate in vaults != 1 +* uniswap callback, flash swaps +* hitting reserve/utilisation limits +* AssetsOutOfOrderOrEqual + + +MISC + +? A really small swap could fail because deposit() results in 0 shares, which causes EVK to revert. Call convertToShares() first? Seems like overkill... +? permit2 instead of regular approval: measure gas savings +* Improve the efficiency of on-chain quoting + * Probably necessary for supporting non-zero slippage swaps + * Use unchecked math in verify() (needs careful boundary analysis) + * Closed-form quoting solutions + * "Range hints" for the binary search + + +IDEAS + +* Currently we have only been supporting stable-stable pairs + * What extra considerations would there be for floating pairs? +* Automatically re-invest fees? There are a few options: + * Don't do anything: Re-deploing probably isn't a huge deal + * Increase the reserves by the fee amount + * Increase the reserves by the extra amount of possible leverage supported by the new fee + * Apply fees to a super-concentrated middle section of the curve (needs R&D) +* Could current reserves be calculated dynamically based on balances/debts/debt limits? + * I guess you would lose a chunk of interest to arbitrage + * Donation attacks? +* What can we do to make this easily integrated with aggregators/MEV bots/etc? + * How to handle a discovery/tracking of the different Maglev instances? + ? Factory? Registry? Maybe a fake factory that reads the actually installed operators from a set of addresses? + ? Transparent proxy so a Maglev address can stay constant \ No newline at end of file From 46cdbf09e03338f01456bfae27d7551528aa4be6 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Tue, 18 Feb 2025 18:23:02 +0100 Subject: [PATCH 129/312] use _msgSender() --- src/EulerSwap.sol | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 837001d..cd37af6 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -131,7 +131,14 @@ contract EulerSwap is IEulerSwap, EVCUtil { reserve1 = uint112(newReserve1); emit Swap( - msg.sender, amount0In, amount1In, amount0Out, amount1Out, uint112(newReserve0), uint112(newReserve1), to + _msgSender(), + amount0In, + amount1In, + amount0Out, + amount1Out, + uint112(newReserve0), + uint112(newReserve1), + to ); } } From d13874fef7a829208986b0e9283867f5e6b8bafd Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Tue, 18 Feb 2025 19:02:25 +0100 Subject: [PATCH 130/312] remove factory --- src/EulerSwapFactory.sol | 109 --------------------------- src/interfaces/IEulerSwapFactory.sol | 24 ------ test/EulerSwapFactoryTest.t.sol | 79 ------------------- 3 files changed, 212 deletions(-) delete mode 100644 src/EulerSwapFactory.sol delete mode 100644 src/interfaces/IEulerSwapFactory.sol delete mode 100644 test/EulerSwapFactoryTest.t.sol diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol deleted file mode 100644 index 7249472..0000000 --- a/src/EulerSwapFactory.sol +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.27; - -import {IEulerSwapFactory} from "./interfaces/IEulerSwapFactory.sol"; -import {IEulerSwap, EulerSwap} from "./EulerSwap.sol"; -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; - -/// @title EulerSwapFactory contract -/// @custom:security-contact security@euler.xyz -/// @author Euler Labs (https://www.eulerlabs.com/) -contract EulerSwapFactory is IEulerSwapFactory, Ownable { - /// @dev An array to store all pools addresses. - address[] public allPools; - /// @dev Mapping to store pool addresses - mapping(bytes32 poolKey => address pool) public getPool; - - event PoolDeployed( - address indexed asset0, - address indexed asset1, - uint256 indexed feeMultiplier, - address swapAccount, - uint256 priceX, - uint256 priceY, - uint256 concentrationX, - uint256 concentrationY, - address pool - ); - - error InvalidQuery(); - - constructor() Ownable(msg.sender) {} - - /// @notice Deploy EulerSwap pool. - function deployPool(DeployParams memory params) external returns (address) { - EulerSwap pool = new EulerSwap( - IEulerSwap.Params({ - vault0: params.vault0, - vault1: params.vault1, - myAccount: params.holder, - debtLimit0: params.debtLimit0, - debtLimit1: params.debtLimit1, - fee: params.fee - }), - IEulerSwap.CurveParams({ - priceX: params.priceX, - priceY: params.priceY, - concentrationX: params.concentrationX, - concentrationY: params.concentrationY - }) - ); - - address poolAsset0 = pool.asset0(); - address poolAsset1 = pool.asset1(); - uint256 feeMultiplier = pool.feeMultiplier(); - - bytes32 poolKey = keccak256( - abi.encode( - poolAsset0, - poolAsset1, - feeMultiplier, - params.holder, - params.priceX, - params.priceY, - params.concentrationX, - params.concentrationY - ) - ); - - getPool[poolKey] = address(pool); - allPools.push(address(pool)); - - emit PoolDeployed( - poolAsset0, - poolAsset1, - feeMultiplier, - params.holder, - params.priceX, - params.priceY, - params.concentrationX, - params.concentrationY, - address(pool) - ); - - return address(pool); - } - - /// @notice Get the length of `allPools` array. - /// @return `allPools` length. - function allPoolsLength() external view returns (uint256) { - return allPools.length; - } - - /// @notice Get a slice of the deployed pools array. - /// @param _start Start index of the slice. - /// @param _end End index of the slice. - /// @return An array containing the slice of the deployed pools. - function getAllPoolsListSlice(uint256 _start, uint256 _end) external view returns (address[] memory) { - uint256 length = allPools.length; - if (_end == type(uint256).max) _end = length; - if (_end < _start || _end > length) revert InvalidQuery(); - - address[] memory allPoolsList = new address[](_end - _start); - for (uint256 i; i < _end - _start; ++i) { - allPoolsList[i] = allPools[_start + i]; - } - - return allPoolsList; - } -} diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol deleted file mode 100644 index 87746c7..0000000 --- a/src/interfaces/IEulerSwapFactory.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.0; - -interface IEulerSwapFactory { - struct DeployParams { - address vault0; - address vault1; - address holder; - uint256 fee; - uint256 priceX; - uint256 priceY; - uint256 concentrationX; - uint256 concentrationY; - uint112 debtLimit0; - uint112 debtLimit1; - } - - function deployPool(DeployParams memory params) external returns (address); - - function allPools(uint256 index) external view returns (address); - function getPool(bytes32 poolKey) external view returns (address); - function allPoolsLength() external view returns (uint256); - function getAllPoolsListSlice(uint256 start, uint256 end) external view returns (address[] memory); -} diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol deleted file mode 100644 index e939056..0000000 --- a/test/EulerSwapFactoryTest.t.sol +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.24; - -import {EulerSwapTestBase, EulerSwap} from "./EulerSwapTestBase.t.sol"; -import {EulerSwapFactory, IEulerSwapFactory} from "../src/EulerSwapFactory.sol"; - -contract EulerSwapFactoryTest is EulerSwapTestBase { - EulerSwapFactory public eulerSwapFactory; - - uint256 minFee = 0.0000000000001e18; - - function setUp() public virtual override { - super.setUp(); - - vm.prank(creator); - eulerSwapFactory = new EulerSwapFactory(); - } - - function testDeployPool() public { - uint256 allPoolsLengthBefore = eulerSwapFactory.allPoolsLength(); - - vm.prank(creator); - EulerSwap eulerSwap = EulerSwap( - eulerSwapFactory.deployPool( - IEulerSwapFactory.DeployParams( - address(eTST), address(eTST2), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 - ) - ) - ); - - uint256 allPoolsLengthAfter = eulerSwapFactory.allPoolsLength(); - bytes32 poolKey = keccak256( - abi.encode( - eulerSwap.asset0(), - eulerSwap.asset1(), - eulerSwap.feeMultiplier(), - eulerSwap.myAccount(), - eulerSwap.priceX(), - eulerSwap.priceY(), - eulerSwap.concentrationX(), - eulerSwap.concentrationY() - ) - ); - - assertEq(allPoolsLengthAfter - allPoolsLengthBefore, 1); - assertEq(eulerSwapFactory.getPool(poolKey), address(eulerSwap)); - assertEq(eulerSwapFactory.getPool(poolKey), address(eulerSwap)); - - address[] memory poolsList = eulerSwapFactory.getAllPoolsListSlice(0, type(uint256).max); - assertEq(poolsList.length, 1); - assertEq(poolsList[0], address(eulerSwap)); - assertEq(eulerSwapFactory.allPools(0), address(eulerSwap)); - } - - function testInvalidGetAllPoolsListSliceQuery() public { - vm.expectRevert(EulerSwapFactory.InvalidQuery.selector); - eulerSwapFactory.getAllPoolsListSlice(1, 0); - } - - function testDeployWithAssetsOutOfOrderOrEqual() public { - vm.prank(creator); - vm.expectRevert(EulerSwap.AssetsOutOfOrderOrEqual.selector); - eulerSwapFactory.deployPool( - IEulerSwapFactory.DeployParams( - address(eTST), address(eTST), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 - ) - ); - } - - function testDeployWithBadFee() public { - vm.prank(creator); - vm.expectRevert(EulerSwap.BadFee.selector); - eulerSwapFactory.deployPool( - IEulerSwapFactory.DeployParams( - address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 - ) - ); - } -} From 8f0df260e4d65b5e6a5397b49d58cb038fcc5b30 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 19 Feb 2025 09:03:35 +0100 Subject: [PATCH 131/312] clean --- src/EulerSwapFactory.sol | 14 +++++++------- src/interfaces/IEulerSwapFactory.sol | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 7249472..97b9cf3 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -3,12 +3,11 @@ pragma solidity ^0.8.27; import {IEulerSwapFactory} from "./interfaces/IEulerSwapFactory.sol"; import {IEulerSwap, EulerSwap} from "./EulerSwap.sol"; -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; /// @title EulerSwapFactory contract /// @custom:security-contact security@euler.xyz /// @author Euler Labs (https://www.eulerlabs.com/) -contract EulerSwapFactory is IEulerSwapFactory, Ownable { +contract EulerSwapFactory is IEulerSwapFactory { /// @dev An array to store all pools addresses. address[] public allPools; /// @dev Mapping to store pool addresses @@ -27,8 +26,7 @@ contract EulerSwapFactory is IEulerSwapFactory, Ownable { ); error InvalidQuery(); - - constructor() Ownable(msg.sender) {} + error AlreadyDeployed(); /// @notice Deploy EulerSwap pool. function deployPool(DeployParams memory params) external returns (address) { @@ -36,7 +34,7 @@ contract EulerSwapFactory is IEulerSwapFactory, Ownable { IEulerSwap.Params({ vault0: params.vault0, vault1: params.vault1, - myAccount: params.holder, + myAccount: params.swapAccount, debtLimit0: params.debtLimit0, debtLimit1: params.debtLimit1, fee: params.fee @@ -58,7 +56,7 @@ contract EulerSwapFactory is IEulerSwapFactory, Ownable { poolAsset0, poolAsset1, feeMultiplier, - params.holder, + params.swapAccount, params.priceX, params.priceY, params.concentrationX, @@ -66,6 +64,8 @@ contract EulerSwapFactory is IEulerSwapFactory, Ownable { ) ); + require(getPool[poolKey] == address(0), AlreadyDeployed()); + getPool[poolKey] = address(pool); allPools.push(address(pool)); @@ -73,7 +73,7 @@ contract EulerSwapFactory is IEulerSwapFactory, Ownable { poolAsset0, poolAsset1, feeMultiplier, - params.holder, + params.swapAccount, params.priceX, params.priceY, params.concentrationX, diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol index 87746c7..f722c0f 100644 --- a/src/interfaces/IEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -5,7 +5,7 @@ interface IEulerSwapFactory { struct DeployParams { address vault0; address vault1; - address holder; + address swapAccount; uint256 fee; uint256 priceX; uint256 priceY; From 48e8bf619091e615d9dc801d133feadf2c1bd4b1 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 19 Feb 2025 09:08:47 +0100 Subject: [PATCH 132/312] test --- test/EulerSwapFactoryTest.t.sol | 79 +++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 test/EulerSwapFactoryTest.t.sol diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol new file mode 100644 index 0000000..e939056 --- /dev/null +++ b/test/EulerSwapFactoryTest.t.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; + +import {EulerSwapTestBase, EulerSwap} from "./EulerSwapTestBase.t.sol"; +import {EulerSwapFactory, IEulerSwapFactory} from "../src/EulerSwapFactory.sol"; + +contract EulerSwapFactoryTest is EulerSwapTestBase { + EulerSwapFactory public eulerSwapFactory; + + uint256 minFee = 0.0000000000001e18; + + function setUp() public virtual override { + super.setUp(); + + vm.prank(creator); + eulerSwapFactory = new EulerSwapFactory(); + } + + function testDeployPool() public { + uint256 allPoolsLengthBefore = eulerSwapFactory.allPoolsLength(); + + vm.prank(creator); + EulerSwap eulerSwap = EulerSwap( + eulerSwapFactory.deployPool( + IEulerSwapFactory.DeployParams( + address(eTST), address(eTST2), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 + ) + ) + ); + + uint256 allPoolsLengthAfter = eulerSwapFactory.allPoolsLength(); + bytes32 poolKey = keccak256( + abi.encode( + eulerSwap.asset0(), + eulerSwap.asset1(), + eulerSwap.feeMultiplier(), + eulerSwap.myAccount(), + eulerSwap.priceX(), + eulerSwap.priceY(), + eulerSwap.concentrationX(), + eulerSwap.concentrationY() + ) + ); + + assertEq(allPoolsLengthAfter - allPoolsLengthBefore, 1); + assertEq(eulerSwapFactory.getPool(poolKey), address(eulerSwap)); + assertEq(eulerSwapFactory.getPool(poolKey), address(eulerSwap)); + + address[] memory poolsList = eulerSwapFactory.getAllPoolsListSlice(0, type(uint256).max); + assertEq(poolsList.length, 1); + assertEq(poolsList[0], address(eulerSwap)); + assertEq(eulerSwapFactory.allPools(0), address(eulerSwap)); + } + + function testInvalidGetAllPoolsListSliceQuery() public { + vm.expectRevert(EulerSwapFactory.InvalidQuery.selector); + eulerSwapFactory.getAllPoolsListSlice(1, 0); + } + + function testDeployWithAssetsOutOfOrderOrEqual() public { + vm.prank(creator); + vm.expectRevert(EulerSwap.AssetsOutOfOrderOrEqual.selector); + eulerSwapFactory.deployPool( + IEulerSwapFactory.DeployParams( + address(eTST), address(eTST), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 + ) + ); + } + + function testDeployWithBadFee() public { + vm.prank(creator); + vm.expectRevert(EulerSwap.BadFee.selector); + eulerSwapFactory.deployPool( + IEulerSwapFactory.DeployParams( + address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 + ) + ); + } +} From e41407806c0f2ed0978e26bbf93111d9a77fa9f8 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 20 Feb 2025 15:11:16 +0100 Subject: [PATCH 133/312] feat: add vaults address to poolKey and event --- src/EulerSwapFactory.sol | 38 ++++++++++++++++++++------------- test/EulerSwapFactoryTest.t.sol | 4 +++- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 97b9cf3..ae1bcd7 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -16,6 +16,8 @@ contract EulerSwapFactory is IEulerSwapFactory { event PoolDeployed( address indexed asset0, address indexed asset1, + address vault0, + address vault1, uint256 indexed feeMultiplier, address swapAccount, uint256 priceX, @@ -51,27 +53,33 @@ contract EulerSwapFactory is IEulerSwapFactory { address poolAsset1 = pool.asset1(); uint256 feeMultiplier = pool.feeMultiplier(); - bytes32 poolKey = keccak256( - abi.encode( - poolAsset0, - poolAsset1, - feeMultiplier, - params.swapAccount, - params.priceX, - params.priceY, - params.concentrationX, - params.concentrationY - ) - ); + { + bytes32 poolKey = keccak256( + abi.encode( + poolAsset0, + poolAsset1, + params.vault0, + params.vault1, + params.swapAccount, + feeMultiplier, + params.priceX, + params.priceY, + params.concentrationX, + params.concentrationY + ) + ); - require(getPool[poolKey] == address(0), AlreadyDeployed()); + require(getPool[poolKey] == address(0), AlreadyDeployed()); - getPool[poolKey] = address(pool); - allPools.push(address(pool)); + getPool[poolKey] = address(pool); + allPools.push(address(pool)); + } emit PoolDeployed( poolAsset0, poolAsset1, + params.vault0, + params.vault1, feeMultiplier, params.swapAccount, params.priceX, diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index e939056..168d7eb 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -33,8 +33,10 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { abi.encode( eulerSwap.asset0(), eulerSwap.asset1(), - eulerSwap.feeMultiplier(), + eulerSwap.vault0(), + eulerSwap.vault1(), eulerSwap.myAccount(), + eulerSwap.feeMultiplier(), eulerSwap.priceX(), eulerSwap.priceY(), eulerSwap.concentrationX(), From 2cf54930074c87028f30257e7baf2262f0cad3b1 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 20 Feb 2025 15:15:41 +0100 Subject: [PATCH 134/312] test --- test/EulerSwapFactoryTest.t.sol | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index 168d7eb..bdcff08 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -52,6 +52,14 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { assertEq(poolsList.length, 1); assertEq(poolsList[0], address(eulerSwap)); assertEq(eulerSwapFactory.allPools(0), address(eulerSwap)); + + vm.prank(creator); + vm.expectRevert(EulerSwapFactory.AlreadyDeployed.selector); + eulerSwapFactory.deployPool( + IEulerSwapFactory.DeployParams( + address(eTST), address(eTST2), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 + ) + ); } function testInvalidGetAllPoolsListSliceQuery() public { From 10608beff496ac0541866883241751c524ec776b Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 24 Feb 2025 18:57:16 +0800 Subject: [PATCH 135/312] scripts --- .env.example | 11 +++++++ .gitignore | 1 + README.md | 5 +++ foundry.toml | 13 ++++++++ script/DeployPool.s.sol | 45 +++++++++++++++++++++++++++ script/DeployProtocol.s.sol | 28 +++++++++++++++++ script/README.md | 13 ++++++++ script/ScriptUtil.s.sol | 15 +++++++++ script/json/DeployPool_input.json | 13 ++++++++ script/json/DeployProtocol_input.json | 3 ++ 10 files changed, 147 insertions(+) create mode 100644 .env.example create mode 100644 script/DeployPool.s.sol create mode 100644 script/DeployProtocol.s.sol create mode 100644 script/README.md create mode 100644 script/ScriptUtil.s.sol create mode 100644 script/json/DeployPool_input.json create mode 100644 script/json/DeployProtocol_input.json diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..7af4ee0 --- /dev/null +++ b/.env.example @@ -0,0 +1,11 @@ +# Private key to interact with contracts using scripts inside /script +WALLET_PRIVATE_KEY=0xa26.. +# RPC +MAINNET_RPC_URL="https://" +ARBITRUM_RPC_URL="https://" +BASE_RPC_URL="https://" + +# Explorer API Key +ETHERSCAN_MAINNET_API_KEY=adada +ETHERSCAN_ARBITRUM_API_KEY=adada +ETHERSCAN_BASE_API_KEY=adada \ No newline at end of file diff --git a/.gitignore b/.gitignore index 64c78d5..6c7f350 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ out/ !/broadcast /broadcast/*/31337/ /broadcast/**/dry-run/ +broadcast/ # Dotenv file .env diff --git a/README.md b/README.md index abbbbe5..fd6817c 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,11 @@ forge test forge coverage ``` +## Private Deployment + +- EulerSwapFactory: 0xB6cFe9b23d18A034cE925Ee84b97D20a52Db1940 +- EulerSwapPeriphery: 0x7fc1edF54d86DfAA90F1069E81D4B520A2A44d2B + ## Safety This software is experimental and is provided "as is" and "as available". diff --git a/foundry.toml b/foundry.toml index 4c9b590..8d0f372 100644 --- a/foundry.toml +++ b/foundry.toml @@ -6,5 +6,18 @@ solc = "0.8.27" optimizer = true optimizer_runs = 10000 gas_reports = ["*"] +fs_permissions = [{ access = "read", path = "./"}] + +[doc] +out = "foundry-docs/" +title = "EulerSwap Contracts Documentation" + +[rpc_endpoints] +mainnet = "${MAINNET_RPC_URL}" +base = "${BASE_RPC_URL}" + +[etherscan] +mainnet = { key = "${ETHERSCAN_MAINNET_API_KEY}" } +base = { key = "${ETHERSCAN_BASE_API_KEY}" } # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/script/DeployPool.s.sol b/script/DeployPool.s.sol new file mode 100644 index 0000000..06a5c9b --- /dev/null +++ b/script/DeployPool.s.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.0; + +import {ScriptUtil} from "./ScriptUtil.s.sol"; +import {IEulerSwapFactory, EulerSwapFactory} from "../src/EulerSwapFactory.sol"; + +/// @title Script to deploy EulerSwapFactory & EulerSwapPeriphery. +contract DeployPool is ScriptUtil { + function run() public { + // load wallet + uint256 deployerKey = vm.envUint("WALLET_PRIVATE_KEY"); + address deployerAddress = vm.rememberKey(deployerKey); + + // load JSON file + string memory inputScriptFileName = "DeployPool_input.json"; + string memory json = _getJsonFile(inputScriptFileName); + + EulerSwapFactory factory = EulerSwapFactory(vm.parseJsonAddress(json, ".factory")); + IEulerSwapFactory.DeployParams memory params = IEulerSwapFactory.DeployParams({ + vault0: vm.parseJsonAddress(json, ".vault0"), + vault1: vm.parseJsonAddress(json, ".vault1"), + swapAccount: vm.parseJsonAddress(json, ".swapAccount"), + fee: vm.parseJsonUint(json, ".fee"), + priceX: vm.parseJsonUint(json, ".priceX"), + priceY: vm.parseJsonUint(json, ".priceY"), + concentrationX: vm.parseJsonUint(json, ".concentrationX"), + concentrationY: vm.parseJsonUint(json, ".concentrationY"), + debtLimit0: uint112(vm.parseJsonUint(json, ".debtLimit0")), + debtLimit1: uint112(vm.parseJsonUint(json, ".debtLimit1")) + }); + + vm.startBroadcast(deployerAddress); + + address pool = factory.deployPool(params); + + string memory outputScriptFileName = "DeployPool_output.json"; + + string memory object; + object = vm.serializeAddress("factory", "deployedPool", pool); + + vm.writeJson(object, string.concat(vm.projectRoot(), "/script/", outputScriptFileName)); + + vm.stopBroadcast(); + } +} diff --git a/script/DeployProtocol.s.sol b/script/DeployProtocol.s.sol new file mode 100644 index 0000000..d478fe2 --- /dev/null +++ b/script/DeployProtocol.s.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.0; + +import {ScriptUtil} from "./ScriptUtil.s.sol"; +import {EulerSwapFactory} from "../src/EulerSwapFactory.sol"; +import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; + +/// @title Script to deploy EulerSwapFactory & EulerSwapPeriphery. +contract DeployProtocol is ScriptUtil { + function run() public { + // load wallet + uint256 deployerKey = vm.envUint("WALLET_PRIVATE_KEY"); + address deployerAddress = vm.rememberKey(deployerKey); + + // load JSON file + string memory inputScriptFileName = "DeployProtocol_input.json"; + string memory json = _getJsonFile(inputScriptFileName); + + address evc = vm.parseJsonAddress(json, ".evc"); + + vm.startBroadcast(deployerAddress); + + new EulerSwapFactory(); + new EulerSwapPeriphery(evc); + + vm.stopBroadcast(); + } +} diff --git a/script/README.md b/script/README.md new file mode 100644 index 0000000..4406b8d --- /dev/null +++ b/script/README.md @@ -0,0 +1,13 @@ +# Forge scripts + +Every script takes inputs via a `ScriptName_input.json` file inside the json directory. + +Before running the scripts, please make sure to fill the `.env` file following the `.env.example`. The main env variables for the script to succefully run, are `WALLET_PRIVATE_KEY` and the `NETWORK_RPC_URL`. + +After filling the `.env` file, make sure to run: `source .env` in your terminal. + +## Deploy protocol + +- Fill the `DeployProtocol_input.json` file with the needed inputs. +- Run `forge script ./script/DeployProtocol.s.sol --rpc-url network_name --broadcast --slow` + diff --git a/script/ScriptUtil.s.sol b/script/ScriptUtil.s.sol new file mode 100644 index 0000000..45caffb --- /dev/null +++ b/script/ScriptUtil.s.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.0; + +import "forge-std/Script.sol"; + +contract ScriptUtil is Script { + function _getJsonFile(string memory _jsonFile) internal view returns (string memory) { + return vm.readFile(_getJsonFilePath(_jsonFile)); + } + + function _getJsonFilePath(string memory _jsonFile) private view returns (string memory) { + string memory root = vm.projectRoot(); + return string.concat(root, "/script/json/", _jsonFile); + } +} diff --git a/script/json/DeployPool_input.json b/script/json/DeployPool_input.json new file mode 100644 index 0000000..2cc282d --- /dev/null +++ b/script/json/DeployPool_input.json @@ -0,0 +1,13 @@ +{ + "factory": "0xB6cFe9b23d18A034cE925Ee84b97D20a52Db1940", + "vault0": "0xa66957e58b60d6b92b850c8773a9ff9b0ba96a65", + "vault1": "0x4212e01c7c8e1c21dea6030c74ae2084f5337bd1", + "swapAccount": "0x0C9a3dd6b8F28529d72d7f9cE918D493519EE383", + "fee": 0, + "priceX": 1e18, + "priceY": 1e18, + "concentrationX": 0.4e18, + "concentrationY": 0.85e18, + "debtLimit0": "1000000000", + "debtLimit1": "1000000000" +} \ No newline at end of file diff --git a/script/json/DeployProtocol_input.json b/script/json/DeployProtocol_input.json new file mode 100644 index 0000000..0c26615 --- /dev/null +++ b/script/json/DeployProtocol_input.json @@ -0,0 +1,3 @@ +{ + "evc": "0x0C9a3dd6b8F28529d72d7f9cE918D493519EE383" +} \ No newline at end of file From 38ecefad365a5d13f78e4187b0e814863210072a Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 24 Feb 2025 18:58:28 +0800 Subject: [PATCH 136/312] update README --- script/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/script/README.md b/script/README.md index 4406b8d..e276fc3 100644 --- a/script/README.md +++ b/script/README.md @@ -11,3 +11,8 @@ After filling the `.env` file, make sure to run: `source .env` in your terminal. - Fill the `DeployProtocol_input.json` file with the needed inputs. - Run `forge script ./script/DeployProtocol.s.sol --rpc-url network_name --broadcast --slow` +## Deploy new pool + +- Fill the `DeployPool_input.json` file with the needed inputs. +- Run `forge script ./script/DeployPool.s.sol --rpc-url network_name --broadcast --slow` + From 13f2307336bbb5352161296aaccc4867f3bb5111 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 24 Feb 2025 19:07:25 +0800 Subject: [PATCH 137/312] update --- .gitignore | 1 + foundry.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6c7f350..93b3270 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ out/ /broadcast/*/31337/ /broadcast/**/dry-run/ broadcast/ +script/DeployPool_output.json # Dotenv file .env diff --git a/foundry.toml b/foundry.toml index 8d0f372..f98f0d0 100644 --- a/foundry.toml +++ b/foundry.toml @@ -6,7 +6,7 @@ solc = "0.8.27" optimizer = true optimizer_runs = 10000 gas_reports = ["*"] -fs_permissions = [{ access = "read", path = "./"}] +fs_permissions = [{ access = "read-write", path = "./"}] [doc] out = "foundry-docs/" From f65395fc5f4af0c349425d7898155f8586bc2e6e Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 24 Feb 2025 20:04:09 +0800 Subject: [PATCH 138/312] fix typo --- script/DeployPool.s.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script/DeployPool.s.sol b/script/DeployPool.s.sol index 06a5c9b..95d0043 100644 --- a/script/DeployPool.s.sol +++ b/script/DeployPool.s.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import {ScriptUtil} from "./ScriptUtil.s.sol"; import {IEulerSwapFactory, EulerSwapFactory} from "../src/EulerSwapFactory.sol"; -/// @title Script to deploy EulerSwapFactory & EulerSwapPeriphery. +/// @title Script to deploy new pool. contract DeployPool is ScriptUtil { function run() public { // load wallet @@ -38,7 +38,7 @@ contract DeployPool is ScriptUtil { string memory object; object = vm.serializeAddress("factory", "deployedPool", pool); - vm.writeJson(object, string.concat(vm.projectRoot(), "/script/", outputScriptFileName)); + vm.writeJson(object, string.concat(vm.projectRoot(), "/script/json/", outputScriptFileName)); vm.stopBroadcast(); } From 6e645a84f51579cab00eaaaa46f4e31e93748dbe Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Tue, 25 Feb 2025 18:14:51 +0800 Subject: [PATCH 139/312] update --- .gitignore | 2 +- script/DeployPool.s.sol | 2 +- script/README.md | 10 ++++++ script/SetOperatorAndActivatePool.s.sol | 31 +++++++++++++++++++ script/SwapExactIn.s.sol | 41 +++++++++++++++++++++++++ script/json/DeployPool_input.json | 10 +++--- script/json/SwapExactIn_input.json | 7 +++++ 7 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 script/SetOperatorAndActivatePool.s.sol create mode 100644 script/SwapExactIn.s.sol create mode 100644 script/json/SwapExactIn_input.json diff --git a/.gitignore b/.gitignore index 93b3270..3c794fe 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ out/ /broadcast/*/31337/ /broadcast/**/dry-run/ broadcast/ -script/DeployPool_output.json +script/json/out/ # Dotenv file .env diff --git a/script/DeployPool.s.sol b/script/DeployPool.s.sol index 95d0043..ea691b9 100644 --- a/script/DeployPool.s.sol +++ b/script/DeployPool.s.sol @@ -38,7 +38,7 @@ contract DeployPool is ScriptUtil { string memory object; object = vm.serializeAddress("factory", "deployedPool", pool); - vm.writeJson(object, string.concat(vm.projectRoot(), "/script/json/", outputScriptFileName)); + vm.writeJson(object, string.concat(vm.projectRoot(), "/script/json/out/", outputScriptFileName)); vm.stopBroadcast(); } diff --git a/script/README.md b/script/README.md index e276fc3..75b384a 100644 --- a/script/README.md +++ b/script/README.md @@ -16,3 +16,13 @@ After filling the `.env` file, make sure to run: `source .env` in your terminal. - Fill the `DeployPool_input.json` file with the needed inputs. - Run `forge script ./script/DeployPool.s.sol --rpc-url network_name --broadcast --slow` +## Activate new pool + +- Fill the `SetOperatorAndActivatePool_input.json` file with the needed inputs. +- Run `forge script ./script/SetOperatorAndActivatePool.s.sol --rpc-url network_name --broadcast --slow` + +## Exact in swap + +- Fill the `SwapExactIn_input.json` file with the needed inputs. +- Run `forge script ./script/SwapExactIn.s.sol --rpc-url network_name --broadcast --slow` + diff --git a/script/SetOperatorAndActivatePool.s.sol b/script/SetOperatorAndActivatePool.s.sol new file mode 100644 index 0000000..98c050d --- /dev/null +++ b/script/SetOperatorAndActivatePool.s.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.0; + +import {ScriptUtil} from "./ScriptUtil.s.sol"; +import {EulerSwap, IEVC} from "../src/EulerSwap.sol"; + +import "forge-std/console2.sol"; + +/// @title Script to deploy new pool. +contract SetOperatorAndActivatePool is ScriptUtil { + function run() public { + // load wallet + uint256 deployerKey = vm.envUint("WALLET_PRIVATE_KEY"); + address deployerAddress = vm.rememberKey(deployerKey); + + // load JSON file + string memory inputScriptFileName = "SetOperatorAndActivatePool_input.json"; + string memory json = _getJsonFile(inputScriptFileName); + + EulerSwap pool = EulerSwap(vm.parseJsonAddress(json, ".pool")); + IEVC evc = IEVC(pool.EVC()); + + vm.startBroadcast(deployerAddress); + + evc.setAccountOperator(deployerAddress, address(pool), true); + + pool.activate(); + + vm.stopBroadcast(); + } +} diff --git a/script/SwapExactIn.s.sol b/script/SwapExactIn.s.sol new file mode 100644 index 0000000..768b68c --- /dev/null +++ b/script/SwapExactIn.s.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.0; + +import {ScriptUtil} from "./ScriptUtil.s.sol"; +import {IERC20, EulerSwap} from "../src/EulerSwap.sol"; +import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; + +import "forge-std/console2.sol"; + +contract SwapExactIn is ScriptUtil { + function run() public { + // load wallet + uint256 swapperKey = vm.envUint("WALLET_PRIVATE_KEY"); + address swapperAddress = vm.rememberKey(swapperKey); + + // load JSON file + string memory inputScriptFileName = "SwapExactIn_input.json"; + string memory json = _getJsonFile(inputScriptFileName); + + EulerSwap pool = EulerSwap(vm.parseJsonAddress(json, ".pool")); + EulerSwapPeriphery periphery = EulerSwapPeriphery(vm.parseJsonAddress(json, ".periphery")); + + address tokenIn = vm.parseJsonAddress(json, ".tokenIn"); + address tokenOut = vm.parseJsonAddress(json, ".tokenOut"); + uint256 amountIn = vm.parseJsonUint(json, ".amountIn"); + bool isAsset0In = tokenIn < tokenOut; + + uint256 expectedAmountOut = periphery.quoteExactInput(address(pool), tokenIn, tokenOut, amountIn); + uint256 swapperBalanceBefore = IERC20(tokenOut).balanceOf(swapperAddress); + + vm.startBroadcast(swapperAddress); + + IERC20(tokenIn).transfer(address(pool), amountIn); + + (isAsset0In) ? pool.swap(0, expectedAmountOut, swapperAddress, "") : pool.swap(expectedAmountOut, 0, swapperAddress, ""); + + require(IERC20(tokenOut).balanceOf(swapperAddress) > swapperBalanceBefore, "noo"); + + vm.stopBroadcast(); + } +} diff --git a/script/json/DeployPool_input.json b/script/json/DeployPool_input.json index 2cc282d..cd1f8c6 100644 --- a/script/json/DeployPool_input.json +++ b/script/json/DeployPool_input.json @@ -2,12 +2,12 @@ "factory": "0xB6cFe9b23d18A034cE925Ee84b97D20a52Db1940", "vault0": "0xa66957e58b60d6b92b850c8773a9ff9b0ba96a65", "vault1": "0x4212e01c7c8e1c21dea6030c74ae2084f5337bd1", - "swapAccount": "0x0C9a3dd6b8F28529d72d7f9cE918D493519EE383", + "swapAccount": "0x603765f9e9B8E3CBACbdf7A6e963B7EAD77AE86f", "fee": 0, "priceX": 1e18, "priceY": 1e18, - "concentrationX": 0.4e18, - "concentrationY": 0.85e18, - "debtLimit0": "1000000000", - "debtLimit1": "1000000000" + "concentrationX": 0.97e18, + "concentrationY": 0.97e18, + "debtLimit0": 2000e6, + "debtLimit1": 2000e6 } \ No newline at end of file diff --git a/script/json/SwapExactIn_input.json b/script/json/SwapExactIn_input.json new file mode 100644 index 0000000..467a61a --- /dev/null +++ b/script/json/SwapExactIn_input.json @@ -0,0 +1,7 @@ +{ + "pool": "0xdFFC67B59708a1c108E4121cabB9AF5A4DB28C17", + "periphery": "0x7fc1edF54d86DfAA90F1069E81D4B520A2A44d2B", + "tokenIn": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "tokenOut": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "amountIn": 20e6 +} \ No newline at end of file From 7847d8dc9f98dfdc88f6e38a1bcb2c73fca4bf7e Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Tue, 25 Feb 2025 18:16:46 +0800 Subject: [PATCH 140/312] update --- script/json/SetOperatorAndActivatePool_input.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 script/json/SetOperatorAndActivatePool_input.json diff --git a/script/json/SetOperatorAndActivatePool_input.json b/script/json/SetOperatorAndActivatePool_input.json new file mode 100644 index 0000000..a478e67 --- /dev/null +++ b/script/json/SetOperatorAndActivatePool_input.json @@ -0,0 +1,3 @@ +{ + "pool": "0xdFFC67B59708a1c108E4121cabB9AF5A4DB28C17" +} \ No newline at end of file From a3349f25427917d0d0ce4670f8a252e495aba455 Mon Sep 17 00:00:00 2001 From: kasperpawlowski Date: Tue, 25 Feb 2025 12:29:34 +0100 Subject: [PATCH 141/312] fix: force approve for incompatible tokens --- src/EulerSwap.sol | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index cd37af6..30b44ad 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -1,14 +1,17 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; +import {SafeERC20, IERC20} from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol"; import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; -import {IEVault, IERC20, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; +import {IEVault, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; import {IUniswapV2Callee} from "./interfaces/IUniswapV2Callee.sol"; import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; import {EVCUtil} from "evc/utils/EVCUtil.sol"; contract EulerSwap is IEulerSwap, EVCUtil { + using SafeERC20 for IERC20; + bytes32 public constant curve = keccak256("EulerSwap v1"); address public immutable vault0; @@ -154,17 +157,17 @@ contract EulerSwap is IEulerSwap, EVCUtil { address permit2 = IEVault(vault0).permit2Address(); if (permit2 == address(0)) { - IERC20(asset0).approve(vault0, type(uint256).max); + IERC20(asset0).forceApprove(vault0, type(uint256).max); } else { - IERC20(asset0).approve(permit2, type(uint256).max); + IERC20(asset0).forceApprove(permit2, type(uint256).max); IAllowanceTransfer(permit2).approve(asset0, vault0, type(uint160).max, type(uint48).max); } permit2 = IEVault(vault1).permit2Address(); if (permit2 == address(0)) { - IERC20(asset1).approve(vault1, type(uint256).max); + IERC20(asset1).forceApprove(vault1, type(uint256).max); } else { - IERC20(asset1).approve(permit2, type(uint256).max); + IERC20(asset1).forceApprove(permit2, type(uint256).max); IAllowanceTransfer(permit2).approve(asset1, vault1, type(uint160).max, type(uint48).max); } From c4de78d520c25c24eafbdc7282be050a2f751e97 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 25 Feb 2025 00:24:17 -0500 Subject: [PATCH 142/312] Use new derivation for `f` --- docs/f.md | 42 ++++++++++++++++++++++++++++++++++++++++ src/EulerSwap.sol | 6 ++++-- test/EulerSwapTest.t.sol | 11 +++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 docs/f.md diff --git a/docs/f.md b/docs/f.md new file mode 100644 index 0000000..fdf610e --- /dev/null +++ b/docs/f.md @@ -0,0 +1,42 @@ +## Implementation of `f` + +### Derivation + +Formula 15 from the whitepaper: + + y0 + (px / py) * (x0 - x) * (c + (1 - c) * (x0 / x)) + +Multiply second term by `x/x`: + + y0 + (px / py) * (x0 - x) * ((c * x) + (1 - c) * x0) / x + +`c` is scaled by `1e18`: + + y0 + (px / py) * (x0 - x) * ((c * x) + (1e18 - c) * x0) / (x * 1e18) + +Re-order division by `py`: + + y0 + px * (x0 - x) * ((c * x) + (1e18 - c) * x0) / (x * 1e18) / py + +Use `mulDiv` to avoid intermediate overflow: + + y0 + Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18) / py + +Round up for both divisions (operation is distributive): + + y0 + (Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil) + (py-1)) / py + +### Boundary Analysis + +Pre-conditions: x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 + +None of the computations for the arguments to `mulDiv` can overflow: + +* Arg 1: `px * (x0 - x)` + * Upper-bound: `1e36*(2**112 - 1) =~ 232 bits` +* Arg 2: `c * x + (1e18 - c) * x0` + * Upper-bound: `1e18*(2**112 - 1)*2 =~ 173 bits` +* Arg 3: `x * 1e18` + * Upper-bound: `1e18*(2**112 - 1) =~ 172 bits` + +If amounts/prices are large, and we travel too far down the curve, then `mulDiv` (or the subsequent `y0` addition) could overflow because its output value cannot be represented as a `uint256`. However, these output values would never be valid anyway, because they exceed `type(uint112).max`. diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index cd37af6..4e198a0 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -7,6 +7,7 @@ import {IUniswapV2Callee} from "./interfaces/IUniswapV2Callee.sol"; import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; import {EVCUtil} from "evc/utils/EVCUtil.sol"; +import {Math} from "openzeppelin-contracts/utils/math/Math.sol"; contract EulerSwap is IEulerSwap, EVCUtil { bytes32 public constant curve = keccak256("EulerSwap v1"); @@ -236,7 +237,8 @@ contract EulerSwap is IEulerSwap, EVCUtil { } /// @dev EulerSwap curve definition - function f(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { - return y0 + px * 1e18 / py * (c * (2 * x0 - xt) / 1e18 + (1e18 - c) * x0 / 1e18 * x0 / xt - x0) / 1e18; + /// Pre-conditions: x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 + function f(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) public pure returns (uint256) { + return y0 + (Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil) + (py - 1)) / py; } } diff --git a/test/EulerSwapTest.t.sol b/test/EulerSwapTest.t.sol index 8e0c72d..e80a509 100644 --- a/test/EulerSwapTest.t.sol +++ b/test/EulerSwapTest.t.sol @@ -175,4 +175,15 @@ contract EulerSwapTest is EulerSwapTestBase { assertGe(getHolderNAV(), origNAV); } } + + function test_fFuncOverflow(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) public view { + x0 = bound(x0, 1, type(uint112).max); + y0 = bound(y0, 0, type(uint112).max); + xt = bound(xt, 1 + x0 / 1e6, x0); // from 1 millionth of the reserves left up + px = bound(px, 1, 1e36); + py = bound(py, 1, 1e36); + c = bound(c, 1, 1e18); + + eulerSwap.f(xt, px, py, x0, y0, c); + } } From b3dfd8548c8580e11ae1ac3bcff501b965032cfb Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 25 Feb 2025 00:51:57 -0500 Subject: [PATCH 143/312] prevent griefing where attacker front-runs dust transfer to trigger E_ZeroShares --- src/EulerSwap.sol | 22 +++++----- test/DepositFailures.t.sol | 88 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 test/DepositFailures.t.sol diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 4e198a0..040c2e4 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.27; import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault, IERC20, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; +import {Errors as EVKErrors} from "evk/EVault/shared/Errors.sol"; import {IUniswapV2Callee} from "./interfaces/IUniswapV2Callee.sol"; import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; @@ -50,6 +51,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { error DifferentEVC(); error AssetsOutOfOrderOrEqual(); error CurveViolation(); + error DepositFailure(bytes reason); modifier nonReentrant() { if (status == 0) activate(); @@ -108,16 +110,10 @@ contract EulerSwap is IEulerSwap, EVCUtil { // Deposit all available funds, adjust received amounts downward to collect fees uint256 amount0In = IERC20(asset0).balanceOf(address(this)); - if (amount0In > 0) { - depositAssets(vault0, amount0In); - amount0In = amount0In * feeMultiplier / 1e18; - } + if (amount0In > 0) amount0In = depositAssets(vault0, amount0In) * feeMultiplier / 1e18; uint256 amount1In = IERC20(asset1).balanceOf(address(this)); - if (amount1In > 0) { - depositAssets(vault1, amount1In); - amount1In = amount1In * feeMultiplier / 1e18; - } + if (amount1In > 0) amount1In = depositAssets(vault1, amount1In) * feeMultiplier / 1e18; // Verify curve invariant is satisified @@ -199,8 +195,12 @@ contract EulerSwap is IEulerSwap, EVCUtil { } } - function depositAssets(address vault, uint256 amount) internal { - IEVault(vault).deposit(amount, myAccount); + function depositAssets(address vault, uint256 amount) internal returns (uint256) { + try IEVault(vault).deposit(amount, myAccount) {} + catch (bytes memory reason) { + require(bytes4(reason) == EVKErrors.E_ZeroShares.selector, DepositFailure(reason)); + return 0; + } if (IEVC(evc).isControllerEnabled(myAccount, vault)) { IEVC(evc).call( @@ -211,6 +211,8 @@ contract EulerSwap is IEulerSwap, EVCUtil { IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IRiskManager.disableController, ())); } } + + return amount; } function myDebt(address vault) internal view returns (uint256) { diff --git a/test/DepositFailures.t.sol b/test/DepositFailures.t.sol new file mode 100644 index 0000000..35d2e47 --- /dev/null +++ b/test/DepositFailures.t.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; + +import {IEVault, IEulerSwap, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; +import {IRMTestFixed} from "evk-test/mocks/IRMTestFixed.sol"; +import {Errors as EVKErrors} from "evk/EVault/shared/Errors.sol"; +import "evk/EVault/shared/Constants.sol" as EVKConstants; + +contract DepositFailuresTest is EulerSwapTestBase { + EulerSwap public eulerSwap; + address public griefer = makeAddr("griefer"); + + function setUp() public virtual override { + super.setUp(); + + eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + } + + function test_griefing() public monotonicHolderNAV { + // Make a borrow to push exchange rate > 1 + + eTST2.setInterestRateModel(address(new IRMTestFixed())); + + mintAndDeposit(griefer, eTST, 100e18); + + vm.prank(griefer); + evc.enableCollateral(griefer, address(eTST)); + vm.prank(griefer); + evc.enableController(griefer, address(eTST2)); + + vm.prank(griefer); + eTST2.borrow(1e18, griefer); + skip(1); + + // Do a swap + + uint256 amountIn = 1e18; + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + assertApproxEqAbs(amountOut, 0.9974e18, 0.0001e18); + + // Honest deposit + assetTST.mint(address(this), amountIn); + assetTST.transfer(address(eulerSwap), amountIn); + + // Griefer front-runs with 1 wei deposit, which rounds down to 0 shares + assetTST2.mint(address(this), 1); + assetTST2.transfer(address(eulerSwap), 1); + + // Naive deposit() would fail with E_ZeroShares + eulerSwap.swap(0, amountOut, address(this), ""); + + assertEq(assetTST2.balanceOf(address(this)), amountOut); + + assertEq(assetTST2.balanceOf(address(eulerSwap)), 1); // griefing transfer was untouched + } + + function test_depositFailure() public monotonicHolderNAV { + // Do a swap + + uint256 amountIn = 1e18; + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + assertApproxEqAbs(amountOut, 0.9974e18, 0.0001e18); + + // Honest deposit + assetTST.mint(address(this), amountIn); + assetTST.transfer(address(eulerSwap), amountIn); + + // Griefer front-runs with 1 wei deposit, which rounds down to 0 shares + assetTST2.mint(address(this), 1); + assetTST2.transfer(address(eulerSwap), 1); + + // Force deposits to fail + eTST2.setHookConfig(address(0), EVKConstants.OP_DEPOSIT); + + vm.expectRevert( + abi.encodeWithSelector( + EulerSwap.DepositFailure.selector, abi.encodeWithSelector(EVKErrors.E_OperationDisabled.selector) + ) + ); + eulerSwap.swap(0, amountOut, address(this), ""); + + assertEq(assetTST2.balanceOf(address(this)), 0); + + assertEq(assetTST2.balanceOf(address(eulerSwap)), 1); // griefing transfer was untouched + } +} From 8dad69d3e2c85b2076407a8623fa0a4d3c97dfe1 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 26 Feb 2025 13:35:25 -0500 Subject: [PATCH 144/312] Improve `f.md` docs slightly --- docs/f.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/f.md b/docs/f.md index fdf610e..54b482b 100644 --- a/docs/f.md +++ b/docs/f.md @@ -1,8 +1,12 @@ ## Implementation of `f` +`f` (aka the "EulerSwap Function") is a parameterisable curve that defines the boundary of permissible points for EulerSwap AMMs. Points on the curve or above and to-the right are allowed, others are not. + +Only formula 3 from the whitepaper is implemented in the EulerSwap core, since this can be used for both domains of the curve by mirroring the parameters. The more complicated formula 4 is a closed-form method for quoting swaps so it can be implemented in a periphery (if desired). + ### Derivation -Formula 15 from the whitepaper: +Formula 3 from the whitepaper: y0 + (px / py) * (x0 - x) * (c + (1 - c) * (x0 / x)) @@ -40,3 +44,5 @@ None of the computations for the arguments to `mulDiv` can overflow: * Upper-bound: `1e18*(2**112 - 1) =~ 172 bits` If amounts/prices are large, and we travel too far down the curve, then `mulDiv` (or the subsequent `y0` addition) could overflow because its output value cannot be represented as a `uint256`. However, these output values would never be valid anyway, because they exceed `type(uint112).max`. + +To see this, consider the case where `mulDiv` fails due to overflow. This means that its result would've been greater than `2**256 - 1`. Dividing this value by the largest allowed value for `py` (`1e36`) gives approximately `2**136`, which is greater than the maximum allowed amount value of `2**112 - 1`. Both the rounding up operation and the final addition of `y0` can only further *increase* this value. This means that all cases where `mulDiv` or the subsequent additions overflow would involve `f()` returning values that are impossible for a swapper to satisfy, so they would revert anyways. From ff22f3b6b72c7dbe864768b115c6833ac121195e Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 27 Feb 2025 21:30:01 +0800 Subject: [PATCH 145/312] update --- README.md | 4 +-- script/README.md | 3 +- script/SwapExactIn.s.sol | 21 +++++-------- script/json/DeployPool_input.json | 2 +- .../SetOperatorAndActivatePool_input.json | 2 +- script/json/SwapExactIn_input.json | 6 ++-- script/util/SwapUtil.sol | 30 +++++++++++++++++++ 7 files changed, 46 insertions(+), 22 deletions(-) create mode 100644 script/util/SwapUtil.sol diff --git a/README.md b/README.md index fd6817c..465c3b2 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,8 @@ forge coverage ## Private Deployment -- EulerSwapFactory: 0xB6cFe9b23d18A034cE925Ee84b97D20a52Db1940 -- EulerSwapPeriphery: 0x7fc1edF54d86DfAA90F1069E81D4B520A2A44d2B +- EulerSwapFactory: 0x04C54FF83e4BC428FD1eDA2f41cdBd583A2e9cF8 +- EulerSwapPeriphery: 0x64A8410D7D2ecF3Aaf32b6C3932e4586f3C42ecE ## Safety diff --git a/script/README.md b/script/README.md index 75b384a..d03cd16 100644 --- a/script/README.md +++ b/script/README.md @@ -23,6 +23,7 @@ After filling the `.env` file, make sure to run: `source .env` in your terminal. ## Exact in swap -- Fill the `SwapExactIn_input.json` file with the needed inputs. +- Fill the `SwapExactIn_input.json` file with the needed inputs. For the `swapUtil` field, use the address of the `SwapUtil` contract deployed in the network you are using: + - For mainnet, use `0xcdd2d349eeD309a0016C9A17f01bF1670913708b` - Run `forge script ./script/SwapExactIn.s.sol --rpc-url network_name --broadcast --slow` diff --git a/script/SwapExactIn.s.sol b/script/SwapExactIn.s.sol index 768b68c..ff0e3ef 100644 --- a/script/SwapExactIn.s.sol +++ b/script/SwapExactIn.s.sol @@ -2,12 +2,12 @@ pragma solidity ^0.8.0; import {ScriptUtil} from "./ScriptUtil.s.sol"; -import {IERC20, EulerSwap} from "../src/EulerSwap.sol"; -import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; - -import "forge-std/console2.sol"; +import {IERC20, SafeERC20, EulerSwap} from "../src/EulerSwap.sol"; +import {SwapUtil} from "./util/SwapUtil.sol"; contract SwapExactIn is ScriptUtil { + using SafeERC20 for IERC20; + function run() public { // load wallet uint256 swapperKey = vm.envUint("WALLET_PRIVATE_KEY"); @@ -17,24 +17,17 @@ contract SwapExactIn is ScriptUtil { string memory inputScriptFileName = "SwapExactIn_input.json"; string memory json = _getJsonFile(inputScriptFileName); + SwapUtil swapUtil = SwapUtil(vm.parseJsonAddress(json, ".swapUtil")); // Do not change address of this one unless u manually deploy new one EulerSwap pool = EulerSwap(vm.parseJsonAddress(json, ".pool")); - EulerSwapPeriphery periphery = EulerSwapPeriphery(vm.parseJsonAddress(json, ".periphery")); - address tokenIn = vm.parseJsonAddress(json, ".tokenIn"); address tokenOut = vm.parseJsonAddress(json, ".tokenOut"); uint256 amountIn = vm.parseJsonUint(json, ".amountIn"); - bool isAsset0In = tokenIn < tokenOut; - - uint256 expectedAmountOut = periphery.quoteExactInput(address(pool), tokenIn, tokenOut, amountIn); - uint256 swapperBalanceBefore = IERC20(tokenOut).balanceOf(swapperAddress); vm.startBroadcast(swapperAddress); - IERC20(tokenIn).transfer(address(pool), amountIn); - - (isAsset0In) ? pool.swap(0, expectedAmountOut, swapperAddress, "") : pool.swap(expectedAmountOut, 0, swapperAddress, ""); + IERC20(tokenIn).forceApprove(address(swapUtil), amountIn); - require(IERC20(tokenOut).balanceOf(swapperAddress) > swapperBalanceBefore, "noo"); + swapUtil.executeSwap(address(pool), tokenIn, tokenOut, amountIn, true); vm.stopBroadcast(); } diff --git a/script/json/DeployPool_input.json b/script/json/DeployPool_input.json index cd1f8c6..ea5e730 100644 --- a/script/json/DeployPool_input.json +++ b/script/json/DeployPool_input.json @@ -1,5 +1,5 @@ { - "factory": "0xB6cFe9b23d18A034cE925Ee84b97D20a52Db1940", + "factory": "0x04C54FF83e4BC428FD1eDA2f41cdBd583A2e9cF8", "vault0": "0xa66957e58b60d6b92b850c8773a9ff9b0ba96a65", "vault1": "0x4212e01c7c8e1c21dea6030c74ae2084f5337bd1", "swapAccount": "0x603765f9e9B8E3CBACbdf7A6e963B7EAD77AE86f", diff --git a/script/json/SetOperatorAndActivatePool_input.json b/script/json/SetOperatorAndActivatePool_input.json index a478e67..e080e1d 100644 --- a/script/json/SetOperatorAndActivatePool_input.json +++ b/script/json/SetOperatorAndActivatePool_input.json @@ -1,3 +1,3 @@ { - "pool": "0xdFFC67B59708a1c108E4121cabB9AF5A4DB28C17" + "pool": "0x67c30405250e395f31d661274352da404e624682" } \ No newline at end of file diff --git a/script/json/SwapExactIn_input.json b/script/json/SwapExactIn_input.json index 467a61a..ce396e8 100644 --- a/script/json/SwapExactIn_input.json +++ b/script/json/SwapExactIn_input.json @@ -1,7 +1,7 @@ { - "pool": "0xdFFC67B59708a1c108E4121cabB9AF5A4DB28C17", - "periphery": "0x7fc1edF54d86DfAA90F1069E81D4B520A2A44d2B", + "pool": "0x67C30405250e395f31d661274352dA404e624682", + "swapUtil": "0xcdd2d349eeD309a0016C9A17f01bF1670913708b", "tokenIn": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "tokenOut": "0xdAC17F958D2ee523a2206206994597C13D831ec7", - "amountIn": 20e6 + "amountIn": 9e6 } \ No newline at end of file diff --git a/script/util/SwapUtil.sol b/script/util/SwapUtil.sol new file mode 100644 index 0000000..4d1772f --- /dev/null +++ b/script/util/SwapUtil.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.0; + +import {IEulerSwapPeriphery} from "../../src/interfaces/IEulerSwapPeriphery.sol"; +import {IERC20, IEulerSwap, SafeERC20} from "../../src/EulerSwap.sol"; + +// This is not meant to be run in production, just for testing purposes +contract SwapUtil { + using SafeERC20 for IERC20; + + IEulerSwapPeriphery public immutable periphery; + + constructor(address peripheryAddr) { + periphery = IEulerSwapPeriphery(peripheryAddr); + } + + function executeSwap(address pool, address tokenIn, address tokenOut, uint256 amount, bool isExactIn) external { + bool isAsset0In = tokenIn < tokenOut; + + (uint256 amountIn, uint256 amountOut) = (isExactIn) + ? (amount, periphery.quoteExactInput(address(pool), tokenIn, tokenOut, amount)) + : (periphery.quoteExactOutput(address(pool), tokenIn, tokenOut, amount), amount); + + IERC20(tokenIn).safeTransferFrom(msg.sender, address(pool), amountIn); + + (isAsset0In) + ? IEulerSwap(pool).swap(0, amountOut, msg.sender, "") + : IEulerSwap(pool).swap(amountOut, 0, msg.sender, ""); + } +} From fbb52e08c039fb0a989765424ec92796f962df31 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Fri, 28 Feb 2025 01:25:16 +0800 Subject: [PATCH 146/312] feat: use create2 & check operator --- src/EulerSwapFactory.sol | 67 +++++++-------- src/interfaces/IEulerSwapFactory.sol | 3 +- test/EulerSwapFactoryTest.t.sol | 124 +++++++++++++++++++-------- test/EulerSwapTestBase.t.sol | 2 +- 4 files changed, 123 insertions(+), 73 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index ae1bcd7..4b7b858 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -3,15 +3,16 @@ pragma solidity ^0.8.27; import {IEulerSwapFactory} from "./interfaces/IEulerSwapFactory.sol"; import {IEulerSwap, EulerSwap} from "./EulerSwap.sol"; +import {EVCUtil} from "ethereum-vault-connector/utils/EVCUtil.sol"; /// @title EulerSwapFactory contract /// @custom:security-contact security@euler.xyz /// @author Euler Labs (https://www.eulerlabs.com/) -contract EulerSwapFactory is IEulerSwapFactory { +contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { /// @dev An array to store all pools addresses. address[] public allPools; - /// @dev Mapping to store pool addresses - mapping(bytes32 poolKey => address pool) public getPool; + /// @dev Mapping between a swap account and deployed pool that is currently set as operator + mapping(address swapAccount => address operator) public swapAccountToPool; event PoolDeployed( address indexed asset0, @@ -28,11 +29,17 @@ contract EulerSwapFactory is IEulerSwapFactory { ); error InvalidQuery(); - error AlreadyDeployed(); + error Unauthorized(); + error OldOperatorStillInstalled(); + error OperatorNotInstalled(); + + constructor(address evc) EVCUtil(evc) {} /// @notice Deploy EulerSwap pool. - function deployPool(DeployParams memory params) external returns (address) { - EulerSwap pool = new EulerSwap( + function deployPool(DeployParams memory params, bytes32 salt) external returns (address) { + require(_msgSender() == params.swapAccount, Unauthorized()); + + EulerSwap pool = new EulerSwap{salt: keccak256(abi.encode(params.swapAccount, salt))}( IEulerSwap.Params({ vault0: params.vault0, vault1: params.vault1, @@ -49,38 +56,18 @@ contract EulerSwapFactory is IEulerSwapFactory { }) ); - address poolAsset0 = pool.asset0(); - address poolAsset1 = pool.asset1(); - uint256 feeMultiplier = pool.feeMultiplier(); - - { - bytes32 poolKey = keccak256( - abi.encode( - poolAsset0, - poolAsset1, - params.vault0, - params.vault1, - params.swapAccount, - feeMultiplier, - params.priceX, - params.priceY, - params.concentrationX, - params.concentrationY - ) - ); - - require(getPool[poolKey] == address(0), AlreadyDeployed()); - - getPool[poolKey] = address(pool); - allPools.push(address(pool)); - } + checkSwapAccountOperators(params.swapAccount, address(pool)); + + EulerSwap(pool).activate(); + + allPools.push(address(pool)); emit PoolDeployed( - poolAsset0, - poolAsset1, + pool.asset0(), + pool.asset1(), params.vault0, params.vault1, - feeMultiplier, + pool.feeMultiplier(), params.swapAccount, params.priceX, params.priceY, @@ -114,4 +101,16 @@ contract EulerSwapFactory is IEulerSwapFactory { return allPoolsList; } + + function checkSwapAccountOperators(address swapAccount, address newPool) internal { + address operator = swapAccountToPool[swapAccount]; + + if (operator != address(0)) { + require(!evc.isAccountOperatorAuthorized(swapAccount, operator), OldOperatorStillInstalled()); + } + + require(evc.isAccountOperatorAuthorized(swapAccount, newPool), OperatorNotInstalled()); + + swapAccountToPool[swapAccount] = newPool; + } } diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol index f722c0f..a11502d 100644 --- a/src/interfaces/IEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -15,10 +15,9 @@ interface IEulerSwapFactory { uint112 debtLimit1; } - function deployPool(DeployParams memory params) external returns (address); + function deployPool(DeployParams memory params, bytes32 salt) external returns (address); function allPools(uint256 index) external view returns (address); - function getPool(bytes32 poolKey) external view returns (address); function allPoolsLength() external view returns (uint256); function getAllPoolsListSlice(uint256 start, uint256 end) external view returns (address[] memory); } diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index bdcff08..c1157aa 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.24; -import {EulerSwapTestBase, EulerSwap} from "./EulerSwapTestBase.t.sol"; +import {EulerSwapTestBase, IEulerSwap, IEVC, EulerSwap} from "./EulerSwapTestBase.t.sol"; import {EulerSwapFactory, IEulerSwapFactory} from "../src/EulerSwapFactory.sol"; contract EulerSwapFactoryTest is EulerSwapTestBase { @@ -13,53 +13,58 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { super.setUp(); vm.prank(creator); - eulerSwapFactory = new EulerSwapFactory(); + eulerSwapFactory = new EulerSwapFactory(address(evc)); } function testDeployPool() public { uint256 allPoolsLengthBefore = eulerSwapFactory.allPoolsLength(); - vm.prank(creator); - EulerSwap eulerSwap = EulerSwap( - eulerSwapFactory.deployPool( - IEulerSwapFactory.DeployParams( - address(eTST), address(eTST2), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 - ) - ) + IEulerSwapFactory.DeployParams memory deployParams = IEulerSwapFactory.DeployParams( + address(eTST), address(eTST2), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 ); + bytes32 salt = bytes32(uint256(1234)); - uint256 allPoolsLengthAfter = eulerSwapFactory.allPoolsLength(); - bytes32 poolKey = keccak256( - abi.encode( - eulerSwap.asset0(), - eulerSwap.asset1(), - eulerSwap.vault0(), - eulerSwap.vault1(), - eulerSwap.myAccount(), - eulerSwap.feeMultiplier(), - eulerSwap.priceX(), - eulerSwap.priceY(), - eulerSwap.concentrationX(), - eulerSwap.concentrationY() - ) - ); + address predictedAddress = predictPoolAddress(address(eulerSwapFactory), deployParams, salt); + + IEVC.BatchItem[] memory items = new IEVC.BatchItem[](2); + items[0] = IEVC.BatchItem({ + onBehalfOfAccount: address(0), + targetContract: address(evc), + value: 0, + data: abi.encodeCall(evc.setAccountOperator, (holder, predictedAddress, true)) + }); + items[1] = IEVC.BatchItem({ + onBehalfOfAccount: holder, + targetContract: address(eulerSwapFactory), + value: 0, + data: abi.encodeCall(EulerSwapFactory.deployPool, (deployParams, salt)) + }); + + vm.prank(holder); + evc.batch(items); + + EulerSwap eulerSwap = EulerSwap(eulerSwapFactory.swapAccountToPool(holder)); + + uint256 allPoolsLengthAfter = eulerSwapFactory.allPoolsLength(); assertEq(allPoolsLengthAfter - allPoolsLengthBefore, 1); - assertEq(eulerSwapFactory.getPool(poolKey), address(eulerSwap)); - assertEq(eulerSwapFactory.getPool(poolKey), address(eulerSwap)); address[] memory poolsList = eulerSwapFactory.getAllPoolsListSlice(0, type(uint256).max); assertEq(poolsList.length, 1); assertEq(poolsList[0], address(eulerSwap)); assertEq(eulerSwapFactory.allPools(0), address(eulerSwap)); - vm.prank(creator); - vm.expectRevert(EulerSwapFactory.AlreadyDeployed.selector); - eulerSwapFactory.deployPool( - IEulerSwapFactory.DeployParams( - address(eTST), address(eTST2), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 - ) - ); + items = new IEVC.BatchItem[](1); + items[0] = IEVC.BatchItem({ + onBehalfOfAccount: holder, + targetContract: address(eulerSwapFactory), + value: 0, + data: abi.encodeCall(EulerSwapFactory.deployPool, (deployParams, bytes32(uint256(12345)))) + }); + + vm.prank(holder); + vm.expectRevert(EulerSwapFactory.OldOperatorStillInstalled.selector); + evc.batch(items); } function testInvalidGetAllPoolsListSliceQuery() public { @@ -68,21 +73,68 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { } function testDeployWithAssetsOutOfOrderOrEqual() public { - vm.prank(creator); + bytes32 salt = bytes32(uint256(1234)); + + vm.prank(holder); vm.expectRevert(EulerSwap.AssetsOutOfOrderOrEqual.selector); eulerSwapFactory.deployPool( IEulerSwapFactory.DeployParams( address(eTST), address(eTST), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 - ) + ), + salt ); } function testDeployWithBadFee() public { - vm.prank(creator); + bytes32 salt = bytes32(uint256(1234)); + + vm.prank(holder); vm.expectRevert(EulerSwap.BadFee.selector); eulerSwapFactory.deployPool( IEulerSwapFactory.DeployParams( address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 + ), + salt + ); + } + + function predictPoolAddress(address factoryAddress, IEulerSwapFactory.DeployParams memory params, bytes32 salt) + internal + pure + returns (address) + { + return address( + uint160( + uint256( + keccak256( + abi.encodePacked( + bytes1(0xff), + factoryAddress, + keccak256(abi.encode(address(params.swapAccount), salt)), + keccak256( + abi.encodePacked( + type(EulerSwap).creationCode, + abi.encode( + IEulerSwap.Params({ + vault0: params.vault0, + vault1: params.vault1, + myAccount: params.swapAccount, + debtLimit0: params.debtLimit0, + debtLimit1: params.debtLimit1, + fee: params.fee + }), + IEulerSwap.CurveParams({ + priceX: params.priceX, + priceY: params.priceY, + concentrationX: params.concentrationX, + concentrationY: params.concentrationY + }) + ) + ) + ) + ) + ) + ) ) ); } diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index dce25c4..43b7c4b 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.24; import {Test, console} from "forge-std/Test.sol"; import {EVaultTestBase, TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; -import {IEulerSwap, EulerSwap} from "../src/EulerSwap.sol"; +import {IEulerSwap, IEVC, EulerSwap} from "../src/EulerSwap.sol"; import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; contract EulerSwapTestBase is EVaultTestBase { From 8ed00b277541d83419219c52197b2f4d1257ec40 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Sat, 1 Mar 2025 19:15:38 +0900 Subject: [PATCH 147/312] feat: swapExactIn() & swapExactOut() --- src/EulerSwap.sol | 6 +++ src/EulerSwapPeriphery.sol | 46 +++++++++++++--- src/interfaces/IEulerSwap.sol | 4 ++ src/interfaces/IEulerSwapPeriphery.sol | 8 +++ test/EulerSwapPeriphery.t.sol | 72 ++++++++++++++++++++++++++ test/EulerSwapTestBase.t.sol | 2 +- 6 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 test/EulerSwapPeriphery.t.sol diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 30b44ad..144c56e 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -150,6 +150,12 @@ contract EulerSwap is IEulerSwap, EVCUtil { return (reserve0, reserve1, status); } + /// @notice Returns the address of the Ethereum Vault Connector (EVC) used by this contract. + /// @return The address of the EVC contract. + function EVC() external view override(EVCUtil, IEulerSwap) returns (address) { + return address(evc); + } + /// @inheritdoc IEulerSwap function activate() public { require(status != 2, Locked()); diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index 2354818..f6a40db 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -3,20 +3,40 @@ pragma solidity ^0.8.27; import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; -import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; import {IEulerSwapPeriphery} from "./interfaces/IEulerSwapPeriphery.sol"; +import {IERC20, IEulerSwap, SafeERC20} from "./EulerSwap.sol"; contract EulerSwapPeriphery is IEulerSwapPeriphery { - address private immutable evc; - - constructor(address evc_) { - evc = evc_; - } + using SafeERC20 for IERC20; error UnsupportedPair(); error OperatorNotInstalled(); error InsufficientReserves(); error InsufficientCash(); + error AmountOutLessThanMin(); + error AmountInMoreThanMax(); + + /// @inheritdoc IEulerSwapPeriphery + function swapExactIn(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin) + external + { + uint256 amountOut = computeQuote(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountIn, true); + + require(amountOut >= amountOutMin, AmountOutLessThanMin()); + + _swap(eulerSwap, tokenIn, tokenOut, amountIn, amountOut); + } + + /// @inheritdoc IEulerSwapPeriphery + function swapExactOut(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut, uint256 amountInMax) + external + { + uint256 amountIn = computeQuote(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountOut, false); + + require(amountIn <= amountInMax, AmountInMoreThanMax()); + + _swap(eulerSwap, tokenIn, tokenOut, amountIn, amountOut); + } /// @inheritdoc IEulerSwapPeriphery function quoteExactInput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn) @@ -36,6 +56,17 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { return computeQuote(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountOut, false); } + function _swap(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut) + internal + { + IERC20(tokenIn).safeTransferFrom(msg.sender, eulerSwap, amountIn); + + bool isAsset0In = tokenIn < tokenOut; + (isAsset0In) + ? IEulerSwap(eulerSwap).swap(0, amountOut, msg.sender, "") + : IEulerSwap(eulerSwap).swap(amountOut, 0, msg.sender, ""); + } + /// @dev High-level quoting function. It handles fees and performs /// state validation, for example that there is sufficient cash available. function computeQuote(IEulerSwap eulerSwap, address tokenIn, address tokenOut, uint256 amount, bool exactIn) @@ -44,7 +75,8 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { returns (uint256) { require( - IEVC(evc).isAccountOperatorAuthorized(eulerSwap.myAccount(), address(eulerSwap)), OperatorNotInstalled() + IEVC(eulerSwap.EVC()).isAccountOperatorAuthorized(eulerSwap.myAccount(), address(eulerSwap)), + OperatorNotInstalled() ); uint256 feeMultiplier = eulerSwap.feeMultiplier(); diff --git a/src/interfaces/IEulerSwap.sol b/src/interfaces/IEulerSwap.sol index b939815..275d068 100644 --- a/src/interfaces/IEulerSwap.sol +++ b/src/interfaces/IEulerSwap.sol @@ -34,6 +34,10 @@ interface IEulerSwap { /// of the swapping curve). function verify(uint256 newReserve0, uint256 newReserve1) external view returns (bool); + /// @notice Returns the address of the Ethereum Vault Connector (EVC) used by this contract. + /// @return The address of the EVC contract. + function EVC() external view returns (address); + // EulerSwap Accessors function curve() external view returns (bytes32); diff --git a/src/interfaces/IEulerSwapPeriphery.sol b/src/interfaces/IEulerSwapPeriphery.sol index 99c97e7..645bca7 100644 --- a/src/interfaces/IEulerSwapPeriphery.sol +++ b/src/interfaces/IEulerSwapPeriphery.sol @@ -2,6 +2,14 @@ pragma solidity >=0.8.0; interface IEulerSwapPeriphery { + /// @notice Swap `amountIn` of `tokenIn` for `tokenOut`, with at least `amountOutMin` received. + function swapExactIn(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin) + external; + + /// @notice Swap `amountOut` of `tokenOut` for `tokenIn`, with at most `amountInMax` paid. + function swapExactOut(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut, uint256 amountInMax) + external; + /// @notice How much `tokenOut` can I get for `amountIn` of `tokenIn`? function quoteExactInput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn) external diff --git a/test/EulerSwapPeriphery.t.sol b/test/EulerSwapPeriphery.t.sol new file mode 100644 index 0000000..7e6f594 --- /dev/null +++ b/test/EulerSwapPeriphery.t.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; + +import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery} from "./EulerSwapTestBase.t.sol"; + +contract EulerSwapPeripheryTest is EulerSwapTestBase { + EulerSwap public eulerSwap; + + function setUp() public virtual override { + super.setUp(); + + eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + } + + function test_SwapExactIn() public { + uint256 amountIn = 1e18; + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(periphery), amountIn); + periphery.swapExactIn(address(eulerSwap), address(assetTST), address(assetTST2), amountIn, amountOut); + vm.stopPrank(); + + assertEq(assetTST2.balanceOf(anyone), amountOut); + } + + function test_SwapExactIn_AmountOutLessThanMin() public { + uint256 amountIn = 1e18; + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(periphery), amountIn); + vm.expectRevert(EulerSwapPeriphery.AmountOutLessThanMin.selector); + periphery.swapExactIn(address(eulerSwap), address(assetTST), address(assetTST2), amountIn, amountOut + 1); + vm.stopPrank(); + } + + function test_SwapExactOut() public { + uint256 amountOut = 1e18; + uint256 amountIn = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(periphery), amountIn); + periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut, amountIn); + vm.stopPrank(); + + assertEq(assetTST2.balanceOf(anyone), amountOut); + } + + function test_SwapExactOut_AmountInMoreThanMax() public { + uint256 amountOut = 1e18; + uint256 amountIn = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(periphery), amountIn); + vm.expectRevert(EulerSwapPeriphery.AmountInMoreThanMax.selector); + periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut * 2, amountIn); + vm.stopPrank(); + } +} diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index dce25c4..4a8e7a1 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -25,7 +25,7 @@ contract EulerSwapTestBase is EVaultTestBase { function setUp() public virtual override { super.setUp(); - periphery = new EulerSwapPeriphery(address(evc)); + periphery = new EulerSwapPeriphery(); // Vault config From ae9ad30795ac82266a9e9a6199e8a01ae1977390 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Sat, 1 Mar 2025 19:22:11 +0900 Subject: [PATCH 148/312] update natspec --- src/EulerSwapPeriphery.sol | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index f6a40db..5d5d26a 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -24,7 +24,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { require(amountOut >= amountOutMin, AmountOutLessThanMin()); - _swap(eulerSwap, tokenIn, tokenOut, amountIn, amountOut); + swap(eulerSwap, tokenIn, tokenOut, amountIn, amountOut); } /// @inheritdoc IEulerSwapPeriphery @@ -35,7 +35,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { require(amountIn <= amountInMax, AmountInMoreThanMax()); - _swap(eulerSwap, tokenIn, tokenOut, amountIn, amountOut); + swap(eulerSwap, tokenIn, tokenOut, amountIn, amountOut); } /// @inheritdoc IEulerSwapPeriphery @@ -56,9 +56,13 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { return computeQuote(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountOut, false); } - function _swap(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut) - internal - { + /// @dev Internal function to execute a token swap through EulerSwap + /// @param eulerSwap The EulerSwap contract address to execute the swap through + /// @param tokenIn The address of the input token being swapped + /// @param tokenOut The address of the output token being received + /// @param amountIn The amount of input tokens to swap + /// @param amountOut The amount of output tokens to receive + function swap(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut) internal { IERC20(tokenIn).safeTransferFrom(msg.sender, eulerSwap, amountIn); bool isAsset0In = tokenIn < tokenOut; @@ -67,8 +71,18 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { : IEulerSwap(eulerSwap).swap(amountOut, 0, msg.sender, ""); } - /// @dev High-level quoting function. It handles fees and performs - /// state validation, for example that there is sufficient cash available. + /// @dev Computes the quote for a swap by applying fees and validating state conditions + /// @param eulerSwap The EulerSwap contract to quote from + /// @param tokenIn The input token address + /// @param tokenOut The output token address + /// @param amount The amount to quote (input amount if exactIn=true, output amount if exactIn=false) + /// @param exactIn True if quoting for exact input amount, false if quoting for exact output amount + /// @return The quoted amount (output amount if exactIn=true, input amount if exactIn=false) + /// @dev Validates: + /// - EulerSwap operator is installed + /// - Token pair is supported + /// - Sufficient reserves exist + /// - Sufficient cash is available function computeQuote(IEulerSwap eulerSwap, address tokenIn, address tokenOut, uint256 amount, bool exactIn) internal view @@ -115,9 +129,17 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { return quote; } + /// @notice Binary searches for the output amount along a swap curve given input parameters /// @dev General-purpose routine for binary searching swapping curves. /// Although some curves may have more efficient closed-form solutions, /// this works with any monotonic curve. + /// @param eulerSwap The EulerSwap contract to search the curve for + /// @param reserve0 Current reserve of asset0 in the pool + /// @param reserve1 Current reserve of asset1 in the pool + /// @param amount The input or output amount depending on exactIn + /// @param exactIn True if amount is input amount, false if amount is output amount + /// @param asset0IsInput True if asset0 is being input, false if asset1 is being input + /// @return output The calculated output amount from the binary search function binarySearch( IEulerSwap eulerSwap, uint112 reserve0, From d33bc26d5753f51334d72a35b46c627a0e571c47 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:04:23 +0900 Subject: [PATCH 149/312] Update interface --- src/EulerSwapFactory.sol | 58 ++++++++++++------------- src/interfaces/IEulerSwapFactory.sol | 19 +++------ test/EulerSwapFactoryTest.t.sol | 64 +++++++++------------------- 3 files changed, 54 insertions(+), 87 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 4b7b858..8828701 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; -import {IEulerSwapFactory} from "./interfaces/IEulerSwapFactory.sol"; -import {IEulerSwap, EulerSwap} from "./EulerSwap.sol"; +import {IEulerSwapFactory, IEulerSwap} from "./interfaces/IEulerSwapFactory.sol"; +import {EulerSwap} from "./EulerSwap.sol"; import {EVCUtil} from "ethereum-vault-connector/utils/EVCUtil.sol"; /// @title EulerSwapFactory contract @@ -35,44 +35,39 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { constructor(address evc) EVCUtil(evc) {} - /// @notice Deploy EulerSwap pool. - function deployPool(DeployParams memory params, bytes32 salt) external returns (address) { - require(_msgSender() == params.swapAccount, Unauthorized()); - - EulerSwap pool = new EulerSwap{salt: keccak256(abi.encode(params.swapAccount, salt))}( - IEulerSwap.Params({ - vault0: params.vault0, - vault1: params.vault1, - myAccount: params.swapAccount, - debtLimit0: params.debtLimit0, - debtLimit1: params.debtLimit1, - fee: params.fee - }), - IEulerSwap.CurveParams({ - priceX: params.priceX, - priceY: params.priceY, - concentrationX: params.concentrationX, - concentrationY: params.concentrationY - }) - ); + /// @notice Deploy a new EulerSwap pool with the given parameters + /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from + /// the swap account address and provided salt parameter. This allows the pool address to be + /// predicted before deployment. + /// @param params Core pool parameters including vaults, account, and fee settings + /// @param curveParams Parameters defining the curve shape including prices and concentrations + /// @param salt Unique value to generate deterministic pool address + /// @return Address of the newly deployed pool + function deployPool(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams, bytes32 salt) + external + returns (address) + { + require(_msgSender() == params.myAccount, Unauthorized()); - checkSwapAccountOperators(params.swapAccount, address(pool)); + EulerSwap pool = new EulerSwap{salt: keccak256(abi.encode(params.myAccount, salt))}(params, curveParams); - EulerSwap(pool).activate(); + checkSwapAccountOperators(params.myAccount, address(pool)); allPools.push(address(pool)); + EulerSwap(pool).activate(); + emit PoolDeployed( pool.asset0(), pool.asset1(), params.vault0, params.vault1, pool.feeMultiplier(), - params.swapAccount, - params.priceX, - params.priceY, - params.concentrationX, - params.concentrationY, + params.myAccount, + curveParams.priceX, + curveParams.priceY, + curveParams.concentrationX, + curveParams.concentrationY, address(pool) ); @@ -102,6 +97,11 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { return allPoolsList; } + /// @notice Validates operator authorization for a swap account. First checks if the account has an existing operator + /// and ensures it is deauthorized. Then verifies the new pool is authorized as an operator. Finally, updates the + /// mapping to track the new pool as the account's operator. + /// @param swapAccount The address of the swap account. + /// @param newPool The address of the new pool. function checkSwapAccountOperators(address swapAccount, address newPool) internal { address operator = swapAccountToPool[swapAccount]; diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol index a11502d..731e898 100644 --- a/src/interfaces/IEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -1,21 +1,12 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.0; -interface IEulerSwapFactory { - struct DeployParams { - address vault0; - address vault1; - address swapAccount; - uint256 fee; - uint256 priceX; - uint256 priceY; - uint256 concentrationX; - uint256 concentrationY; - uint112 debtLimit0; - uint112 debtLimit1; - } +import {IEulerSwap} from "./IEulerSwap.sol"; - function deployPool(DeployParams memory params, bytes32 salt) external returns (address); +interface IEulerSwapFactory { + function deployPool(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams, bytes32 salt) + external + returns (address); function allPools(uint256 index) external view returns (address); function allPoolsLength() external view returns (uint256); diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index c1157aa..384fdb3 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -19,12 +19,11 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { function testDeployPool() public { uint256 allPoolsLengthBefore = eulerSwapFactory.allPoolsLength(); - IEulerSwapFactory.DeployParams memory deployParams = IEulerSwapFactory.DeployParams( - address(eTST), address(eTST2), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 - ); bytes32 salt = bytes32(uint256(1234)); + IEulerSwap.Params memory poolParams = IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 0); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 50e18, 50e18); - address predictedAddress = predictPoolAddress(address(eulerSwapFactory), deployParams, salt); + address predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); IEVC.BatchItem[] memory items = new IEVC.BatchItem[](2); @@ -38,7 +37,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { onBehalfOfAccount: holder, targetContract: address(eulerSwapFactory), value: 0, - data: abi.encodeCall(EulerSwapFactory.deployPool, (deployParams, salt)) + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) }); vm.prank(holder); @@ -59,12 +58,12 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { onBehalfOfAccount: holder, targetContract: address(eulerSwapFactory), value: 0, - data: abi.encodeCall(EulerSwapFactory.deployPool, (deployParams, bytes32(uint256(12345)))) + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, bytes32(uint256(12345)))) }); vm.prank(holder); vm.expectRevert(EulerSwapFactory.OldOperatorStillInstalled.selector); - evc.batch(items); + evc.batch(items); } function testInvalidGetAllPoolsListSliceQuery() public { @@ -74,35 +73,30 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { function testDeployWithAssetsOutOfOrderOrEqual() public { bytes32 salt = bytes32(uint256(1234)); + IEulerSwap.Params memory poolParams = IEulerSwap.Params(address(eTST), address(eTST), holder, 1e18, 1e18, 0); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 50e18, 50e18); vm.prank(holder); vm.expectRevert(EulerSwap.AssetsOutOfOrderOrEqual.selector); - eulerSwapFactory.deployPool( - IEulerSwapFactory.DeployParams( - address(eTST), address(eTST), holder, 0, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 - ), - salt - ); + eulerSwapFactory.deployPool(poolParams, curveParams, salt); } function testDeployWithBadFee() public { bytes32 salt = bytes32(uint256(1234)); + IEulerSwap.Params memory poolParams = IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 50e18, 50e18); vm.prank(holder); vm.expectRevert(EulerSwap.BadFee.selector); - eulerSwapFactory.deployPool( - IEulerSwapFactory.DeployParams( - address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 - ), - salt - ); + eulerSwapFactory.deployPool(poolParams, curveParams, salt); } - function predictPoolAddress(address factoryAddress, IEulerSwapFactory.DeployParams memory params, bytes32 salt) - internal - pure - returns (address) - { + function predictPoolAddress( + address factoryAddress, + IEulerSwap.Params memory poolParams, + IEulerSwap.CurveParams memory curveParams, + bytes32 salt + ) internal pure returns (address) { return address( uint160( uint256( @@ -110,27 +104,9 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { abi.encodePacked( bytes1(0xff), factoryAddress, - keccak256(abi.encode(address(params.swapAccount), salt)), + keccak256(abi.encode(address(poolParams.myAccount), salt)), keccak256( - abi.encodePacked( - type(EulerSwap).creationCode, - abi.encode( - IEulerSwap.Params({ - vault0: params.vault0, - vault1: params.vault1, - myAccount: params.swapAccount, - debtLimit0: params.debtLimit0, - debtLimit1: params.debtLimit1, - fee: params.fee - }), - IEulerSwap.CurveParams({ - priceX: params.priceX, - priceY: params.priceY, - concentrationX: params.concentrationX, - concentrationY: params.concentrationY - }) - ) - ) + abi.encodePacked(type(EulerSwap).creationCode, abi.encode(poolParams, curveParams)) ) ) ) From 8df1cc92a7538be064eab1d860577d19144ee050 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Sat, 1 Mar 2025 20:05:26 +0900 Subject: [PATCH 150/312] refactor: removed un-needed event --- src/EulerSwap.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 30b44ad..b3c69b9 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -34,7 +34,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { uint112 public reserve1; uint32 public status; // 0 = unactivated, 1 = unlocked, 2 = locked - event EulerSwapCreated(address indexed eulerSwap, address indexed asset0, address indexed asset1); event Swap( address indexed sender, uint256 amount0In, @@ -88,8 +87,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { priceY = curveParams.priceY; concentrationX = curveParams.concentrationX; concentrationY = curveParams.concentrationY; - - emit EulerSwapCreated(address(this), asset0Addr, asset1Addr); } /// @inheritdoc IEulerSwap From c977e4f767a4a2a779db8461afd661397947bd7a Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 2 Mar 2025 12:22:11 +0000 Subject: [PATCH 151/312] feat: revised white paper --- docs/whitepaper/.DS_Store | Bin 0 -> 6148 bytes docs/whitepaper/EulerSwap_White_Paper.pdf | Bin 0 -> 356093 bytes docs/whitepaper/curve.png | Bin 0 -> 262544 bytes docs/whitepaper/main.tex | 390 ++++++++++++++++++++++ 4 files changed, 390 insertions(+) create mode 100644 docs/whitepaper/.DS_Store create mode 100644 docs/whitepaper/EulerSwap_White_Paper.pdf create mode 100644 docs/whitepaper/curve.png create mode 100644 docs/whitepaper/main.tex diff --git a/docs/whitepaper/.DS_Store b/docs/whitepaper/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 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ප_n1d1lQ0{W4J<+@uJ+M+btzuItb_ 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

-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 dwz552Xii|-IlwH@lq$l-(rB zWZ3A3 ZO``* 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Рe`R=VlR?L2^vw7@i!n5B64zv8kP_?vnv@?9e zHY$<)NpdqGe|L*yPy3OnW(wV@4oT`0`YisIM;EYum{#p${Xwq#)neq6hy(AO zevJ^?Vqn?1D{7f{*=Fzd#Uiyh!o8#HQ9R^F=QW!ZIMFsCV!oTGluyf=czTU zBw8}qq^)rq_7_e(yq`nvKR%E+uw|mP&ttZ5?MO4y|J$o) zd-qq@T8XpQ50ztDjr8#{awo%O$59*5p^Ta8#-DFq~td#P6oNk(fB=km4w!=3babc#SDPr@vknRVi-@u-z z!-me}`goj--^97z3EU4_W>q?y-~c6(E|Al-uC!SKdpp#Q?o9u0Zc zpkE}K0#Z13mZd$#CM`^^vO$L{(go<+l!M+|e<4M;ukNft%uQFSMYCd%*lcV-^!pfm zJh8+lSZFQ2;95v+BH6%eEz4F;V^U?}N|GHEM|}%NiavFH{Rl-*`mh8=Ft^LeI1*tJuc^m2pB%m~STaew`LkLKk$nSPB#k8|?CKiL-XYpscbx3K$ zi9Z+r3hCsCnNbRR|H+8s!MlH4XrWtU-JC-Q-DNMV+4nHayCXE^<_h$tu!CgFcQ6T# zC+g$+=PI36x%N#IF&r6j_v?c#rIjw!xpDb$^;6~?$vPuW^dCCA6^!_KP)pt2lM#*9 zhI%pfYiak*Z3!(lOWnk5H9TJAy}2V^1v625slw6U;cXu7{G#(}lIV|%tRO>~nW)~V z=R*`)YpBAVa~so3t-S&H%0tRZsbjg0q?!jWcP#7~y1C9uW|g6%^v>{n`xqfXoZW7L z>USYZw=Ve84elZ9BUau8{dMmhuX=wrxT7yU3s@=d3zKS&p6xqBNQG57cmu(fi)(G= zKKfB+>+#`RSb}MmQ80VI27TuMOXigiBPActqxYTQW*AKe$8Ezd3g5}Vd0lE6zc z-UrrY*V=SDA@n@|ruku0WX2qqsqd&3-z;rBR}|bGWi44~DxNStf<0=h_O8v&Qic&p zH-7&-UcMbDS9>!)Dx?W7c1_w8_|YQedNl)fW*2$WtyRZ*Ese?wHT4azKSOI>a5ALt zSAiIqKJPhbOi=jdc$M9575qGH_z+LRW?-lR#dsq@wAo~XF#`488P(`URGTu}e*Q6f zmJe?!+Y2(yPXju)bTZGsLMCIXDj-I?t^M`Jsz1tlc$$i7CR6F5W_R4vA+9}U z4vcAp)pzxeewTE#EginVIO>{~*ST)1G#$Umi`6|BDHYrrA6bes%&ZS58jFhO!w}6M zk@(EVk5RFoJ9y6bX(%~*rqb0+!1`XdX1I6Vo;K%<}~BUo{k;G(Oil4(A~E8XpmT6baR|X&v-421d5zpkjMI z`J<+P-!2rzfQnPib8gFcFL&Y_oCN#|4ntH zz9*gQ9YY0s^lY0O!`y96P4r;6i_|YIWK^fJOrBq5*Vi^59P5LQ-O1pF6;u-JVu_LS zaDHXp7o=Wt?Xrk^d>85d!Y7{>7~T548|k0{739n#9-zy9GN0-73x&{1qkeLl;S9#M z!)R^dnb#hYaDq-hOnd3WUJj{qMDEZYK0a+$F9>*+ap`d~wl#2Nu z`o{Lxk9kj9?&zN3Zwe!RlIdcv|LmY)G*_1VNd>wOJ9W}=zHCC6`eey`iKX7d`jP59 zIjqJk%sB(aaBa$x%$0XFb7A%l=dkITb!@w$4RmUlU0kHh>htZvS~(@56ilp*S@KX~ zO;BNSwA?Y__&x>s@Vt3yc^d8qp_6`YZYxS$ui=X{!)1T6wCmZ2$X)fhw*B>x*)K7t zRpP}`{<@2iu#p*Pj6uH+R_~__3c8-G-@d5e#eC#@*Rt+$rrqC03_8FpV6i5=8@8_9 z=lJe+FJpLQX{Kny)`I+Y&QQS6#ZIZ(FXQ2i?-l~pF{&&n*M=6gRWF+Ut;ixw)jK@= zqb)_&838tI0TM|m3a2^D zZ`%cika2o3!S+K_qUp8Vi(6)*Ys<^QCpF9}T$8K8<#R554eA~oVx*=lZ0DJB`lQ41 znq!m-4t2T7(KcKysm*KG9*%Pxm^{lE!I5`QPm~zmLGf>LTGAWB_9fB8IYugQ1uG9= zC07DkU7b5Ow)6Z|SG~*QBo4HZCp4?)-i{ zL3Yj;ISE=Bg)Y+~?gw=ZDWZDdURNcTeltQ}=d7DC&R@N3C);7x)q!q6SS41iX6=Dr zE32AO!w{E@0;UcsJ$~McJB3H8ONo%7=nBmczsAfeoz84(pmcX4l%;vBcCK!LLE-1i z+2PlDcI1Bw534%box5-G5yJQ^81uX%6R-Wzgk;gWUk{F%0n)A4dRtHU^O}ynJ$413 z8xzwkJ@Lz^7`Tv_g^!a{Y5O-hfy}0)5-Te$hhfVJ)_!qg{|XkJ`R)Nz5G^6Lm=)2t zqSk???y&BcQyKee_z%T|88{Sf+ZK?1eF^sA?dV;S{KsvaS)Z^im}BbonHW*Z?o_re zO?lvGt;?_lXW>@w`zoMF!-gtVD*1~Uey(ULT}YG7i2JvfTdD+Kb8xGlDwNU<+oo3>cfN179D~NQDT=tbuK&P z%9C>s=(*lcLvdoC-WxZ1ukJb0PJ(tswJlm(I+aJabBnHiv9W;mQxrJP(20jN4sk;F zo5Da8(FlGZ2U`aoCf6#qeJRR8i-~|RDRS@ZCucCW(je!3c(tv=AU#w6Ep@v>q2%ht2V} z%_EshwYZ)4nDvMJwRT9pHOiflOYV=53zc*|R&C)H!V@l4Lwlr+1{slaqmybDnp+WU zL0`EP@tzum$p*ev7xN50ZGS4y%*@+e2H*3XI79PYAWQ8-H_=YIAYS-8M3*b@U-EEii=&S7x7&}4S(CZo+G)-Deexe0CaGjYDa3le`fKrL zYB_&9AS}PqCd{U#_BvHL8dByPJ;bkSl+Xvmsv+xW(=8u)=p|_N7tnS*YRl~4E@X^W zc?0>B+}MMGYV=`+23zl^`NNWOu6E?*z>hRBF2(^`Hv`l!{U^G-p{Fbb5Kb&DHv}vUvoq{W!SaE$#3*@C5 z+sMvPOcSd|%QJk3YS7Tp9wu=m>RL6kGzdN}rhgf&Hf05mX*1$Y9&NF&8$#B+s;1}n zd|q9yUfoa~KS^<_$|fxeP0zyQz?<13!D@hanh5_T{uj$vkYH1`*D|@Xz&X-#_k}8_ zW{+|?YzV$>?tO@i%1S)FW_=8a^!{Q@yiR$Fb6JI1o6q98sWLv9-a)O^IN}JQG(nYe ziC{0YYBNb6YpwR6w38*mHu9yWk>7GUjUm^SSdfyAvA@d7`9R9x3hmBs0V*@ z5aSDna-BH^ceiaT``|R?8N#GWHdlBb%A%+bPFpx<@hXL#d;;OFtd_9iVz|vB%DA`E zeyHF>oJG)-(^=0?a&18rTpLI=Cz{yOhCt6G;*deVl zdeO}{CLvNDE^nsZpO2bhp~avc!Ip`FLqiTzBj${rDBSdVSnMi-I3wjn5sT|qQe@!gW#BAsSqQt3OiNV}jYteRMDsXYbfqME@b72D zx6XQyK53rAsL|TEl5@R6%f)xPQd5iC&S#%}AArsc)f}rVblksQ^CXLTGGJvrQ6Mmq zQ#)^QjXryNm4{f3(%YhIf9S^Tp^-}{o~Jhn9le&WMBT0G%_iTx#!%P>^;xls&G~QZX2#m9-5H{KN#%HPrCpXXjKa$P(-xX#Pb+ z89yU50Kk-^X@ZX)I!;selDU}MVPSEVti*nqd}Obu-Zc#5@qI_W!brWWh?I3N)G*Wi z29lax!LAUTG?F?IQwJ2w*BRX4b#aQ1#ZRfvbKO$rD1RcbF_2}e z>%s5GT(Nsphhia`P+`15j%Hxt8a!Xc@q@CfAI3PV?*0kN+)X#9Dn8o+nZkFa=yK;c zt69U#=^7y&2~03;FuStXv3?Hbax_%*NG|j~ocT;fhg+-b~`Ny z0CAVdTbMq-SHQen}xqKme6*PPn=vQUU>8SasP=6|nZ&PYD&)bjn&ia;I z==Ur{_UJ@C0bM-h);|OQt4QknUEQ(?yB2u>6Gp>KiS&l&K0mZ8=B@*ys*3h|rL>gP z@GmQE97nzx*Fsq*Wm*q{yE}AnfYr&S9U=P7XnsUuFsmzVnerO zmSH&8r<%-deuTTZ<@N081iyNjiu^)i_Q0!?k8G`Zay&-~AwV{mx8I*Ltk*@kx`3C{ zamMjx)yWmJ$t@lEdZZB9Kz{7mq|)s@x5+2rH{DQ|gKbBL=afiEitdBEA`C)&NNJp} zC{$N+levWAertN&8KPz>;biHNU^x{*0xN;f)CZj!WlimF&~jfW)8(0HVEBr*`Wv!( z%&4-49J7D+ld{v>$&U<>tl{aZb3>5&rm^gxHN56yuLumc4^GlDyKuMlO&OesecNJj z#7w@v4?}H=7_p4$PlnrLVqV{QYv;8C19Kn5SK^Fm)Qj>HZsJ6-sa;W`?g!0ng5W9tnNsD(VlGTi%s6~A@wlf;V~@l))_* zU493*6E$0Vc!A*zT_BwnA(mUrZrS&VrCa!}8=irQqSZ6Uywa{sHzxMt%25B(T&4wZQCNydSus-f*lSniSHq!J)a0xb9o!)!ASd+&yN_p-@tv4l}vk2@Oc|G*a*`K*NiOP!& zR%kx5(C;!f34}0E^3Q^BkqK+@bL7YNaLe0th(zG0ww7~(66O+TBm@3(t`-(J{E5Zv ztv)WuUvt*5o798%*_^WBgDT#=!eu}Y-b$0zor@}u4b3enithl6T-W7^Gop0-q!?~6 z?BbCkOJmWx=(GzHo3Wa!0NICqab%Z-cF8{{6OjC#bKYEM9g1irFMz*}f#8!c@Mk)>kozPFxB)Iwc9fakHTI{KXSY#zT?FiAH|{WF9vYE zMK>Z~vm@K*xNvf+kHXR>u+nbR?Y+A|7}F6;S|!gq$3qdYO+&rC(wfY3YCifNevMQe zzYM<978Hu7!;xPpuzYn2^E5K@=J)lQ%DbHEvag@F`Dq(R3r@h8eA#kLda1hnY z62M`9N>j=UV6S9>iTyKQhyMi1Jl`r}C1#ZIwdGu!M>O=zuES!?ym+oGoabkPM2oGJ z9-eIwj09dgn@Q%S0V{*OHSQ*UiPE0kBMtP**#*2V@?u`(Azrz|H-3K)%`xweU1(1x zWbrFz)p3u#6qoztI{V&8GF+}tif@Z3jyQ)jTnzd=;|+pjDwZqxYq(`&+R;DOelfJ_ z>9?Dwlx7wkmgAr}f#z%Q*c1b?Y~ua!%O_cgNskKF*0Gk(aKxtQfw?wTn{%W3HTncS zY+K4biODMy`-NsANqV*vm(xv>oUrOgIo^z5jELTWgp66ELp9_NJw-&z6iTpT^hwPr zm3aA+NMmkX>hBBXmkdcOTuRTVId6SKM!(-Yj?>-TC=`0kv?q$M8vrv;H0*NY#JClz zQbe8e*h7|ej+1dVvkh`l>FQ}7%8F+XsDi_VoTjKjqtm=Oodhql;v^*~>T{9L5L(RS z+G4$Oj;8Pivd!4P$jSg)_%P0E{`iZ1D)Wy$hZ3fsT#e$TP)0hujq%gSsVUS48sk$t z*qCws$KP#S2;B%mke=7cH(R1o(xc-F>1y;5+&61jV_QFRPFyxRKH=7~tqR|GG+382 z$Cnf`DuNvK#mq4)E`zcV|YxW39@GjP+ccMfS*Tr$ubyGxhf2 z+3~4f_d>uNCNHmuD|;m9@LOxCy00_q;g?>D9k@5r4S<6tqi1?}Mbq4+b7Vwnf;R;) zPJH&euvs*OuAc$4A zN-PJo%{6?|+=n*&JSdwi6{>$nh&joqDgV>&Q%~~wQR%YlL}ICygT~VtbWc2YDFV-e zV}&uVB96|6Y9DGDQwM|Dx|Dx+0TcDuVDNs{PV}&^OOPr^P57Fj9A$z%T#mn7NGlr$4P=Zx&GZl+mZ{cb4&Iv(> zq?ymqlC-i5;H8xkaz2T-QV+x4my@ z8&RB3^V5fcM0lyaO_d9EL}J1zr=!lk-Xq!w0P8)p(ZqDUT$Lp^H!i;jpZ*OI{p>Ao zETxzHIw^mhc~K}2$2D+hU%P-^oQ>o@n+=GqtNmsa!RV~LZ{ViVf z7zPlO?s2J-bH;>g6vHv8w;wkS63p=)$M_Ice4Gx)$me!HP?a7y>{<# z;;?uMDba->fX5f;DF^Hlf+M+YKPI9hM9|2b9wYiBJNcOL8<{3Ahh6_*lvzRnx4irK z6V2VE^ABZy4Yt+$7wr+TgKE1IEEA?sOkI;e$HVx(WaSD-g$@FU<$+>rPuN zWY;q$&#PwFTH+sD)Ke!o}_9&rt`6qUf#H{vdF}HI*wjnRe$k{Ee z_3%|c>np7}r8;zJ0oCht&C$loHLv~dgS%dzM7@>DqJ$IoXk$T!!VcH&MtK<{bmrJTz;57X@!r(1}LvdJYdKyL0uC?p2b zv9qJR1D2o#yi-Er=aPxv_(v;G+k4;9<7jznm};X{(Q9^$-sWEUH6PDtnEA(sYD;C7 zo2#Gn6kYYq=>Aq9#QvONKXs=QUe1?ZR*=cQ9jh*r9f9~n@eKGa_4@DJ*sOWitfNga zr)f-UU9_k%wk1C+s>_ut2=lXi@5s3MTjI=#m0^HjfV5s;AwVU)Bam7fSGj+9jt7}u zu9=~YBePUphM8qgs69{&k+(B<&mA7F#9LqGYttF?N_(mxdN07E00YY2R8cCi~ zmpJwmES95S<+(lk;yJJsZT^`QSu&8|j`o20z+;U0U_$-{Sb5`*KdNq!LK`eFymkdz zJt^%AbZtNuv|+8FDgHj|7_K%rZ_o%?RPq_lZSs?6^zw*PTmiefP}I$u2;66&GdjL} zCLm4&MU0pn?@OENq`6;D%5wyl$szTGiehMLl*+)KAaZ(srSgO}q&xCz`mbrI9^#6c zTn0|2tJn*uwT-a*B*T6nNGnqr?2_UtSZO|5WlODK;q2 z8ResRVTYnRD38TMA}FrM{P~6FMaJ(5{!TtOfN#*w$8<<75Bqh=Obk3PL-HmgB4|bi z#oKg#hnX3kkGXM&xhQBR8k&z;<0fM~Xl4@dGKto2hKO*hoAkDVUqA8v5l-->9M6k6$A3Cm3-)i0%|DL2|1j+d z+S=OvP26Y^{^Pv+Cv*c~`B!oV!19l`@1N^`PMOj_X`BDd=lq|%&Hs;l4$D6;@i*f0 z@AEnT-2Xq`@P9%SF*CCR{@cmk)RIoxZ$a*vsnxg5{2fWYm5)b&qIS_xnJslue%JpL zK;vMh{wKUa!h`plPj6o^0r!N7TWfls6b0;uz`pSF@}^3{rkUu|k}R_Cx2xOzcv_%| ziLPZ$W2YOoT3aeDbL27j{^};zyFt89WwZF@*kq|X+dabiO8jar0N=DDV`Zvzc#Z;C=W=$`O4e^-+@p&N4cQwvPQv@(| z(gkc^mj+6nLBC3;q>bndIQZq$6ij3MByGjk z_n%(;Oxb(aZCu+`5GR8uc6Y+b!qqo~PM_wp+f1t#U+l#%31;Rf7h$t{-S-iOuh+}g zpp6QpRmi zY3ghdNDy3i{CeJ!NyU||a_x^5Tx~i+(hFgFt-x{%mq%sxsAw_UZ_hbiotuAr8*wt> zc|De|2tHN66+}IDFIC^$xF2jwmPQ0ku&QcXb@sy|Nva3$NB2EPCl-7?un<3+`c+bC zJiiMHr;0GT>ba~p>~(xQRg@Tf+nNVr{6|+NePWgeZPb=~Un;3tknl61qVee2Sam{f zW4$gy+J`OI@NiR+Wj-YY4{BD~3-sP??~tfh)U0r9z4F#Z>a-A3)-y|ZXIZeG4Y6Pi zXYF}Bt+oZ~K4@JX8%2y3x(i^tPu50n_84N6IXgTuyn(?lKiV!!?qokfO|e2QDr%gp zoDrWccfW|X7Io)u{dvjbiZSsC1+9vl6YS$w%Me)x z>tN-f15D@(V{%}!)8(NS57i6#dzzB<|M=%q(<1lkcpv$lZ-ZL4J~!K~s`*^%4f2t8 zWd-uK-UWIE(IlE&IQ0jNMaWSYmZjk{T-_(rKIB<^Q58_iK*x#aRMhPQr+{be5>XV< zV7fV*YHb6XO=yrdLQ$U)@Fc=^x)W4Gia0 zAsr}tnjNZb4egG<_#gWgcvi9aXM;ww&9de+W`ml@phwlVwg$d?>|)+q+OMU7zz#7^ zZ$*bT3@V(QPh)FlPc+(xyszyKc`n4}*?fM*_^tGt+y32p;3}6yO8OK$P0~-r@#)t@ zs^p0M6kL-{bI>0mT>}vWUoORvjXAK728Er*c?=5oEyOFmGx<52LzzgSfs}%Q>YBvm zfdQ#&QY4oXB+z{Rk(>=o;kAU%X2t*PDs4N;5XG_*a%hW#RlzF5yoHDt*ze=0iv-D8 z-__uJQIl@y+l2zHOH->Ej?XZJjgUFiF~axca%N2J%&xXJ$ZW*$Yq6c~gcOYfxo2Mm zuMa7|Wn((+;E36pH4+J6yy> zxZ>BZo-0o`HIe(Ur~bfQ&qG`=d^deJp9^gKnsxCR$JvvM<@)2~c)t;Vmz#j=r(}O?fUK*|fOz(RBSg6j27wY|o^Cpy>Y(gz zF*%cxqrgEAsr77Hwba!5*WzkBr4=$GLI z`FA!>^r1}3GN~)dgC zRuNw~iHuOJStLKQ^XyXN&>mV8%LY>W5ZZPlC!!CZG?am6KSzB6R@p@`Ba*`|iiPx0 z95{c`d>qVPhJ1R-L0xb3u~Yq1t+&aGT4@O12^!ktOeFt3JC!PMb~%W{{KgceFGfuA0KKCJPQ z|DK#_Dy6YLhWhry3|aVkUD!mdelfx6poP(%jJ$-q2aa}7)}H@nJ!_RL~?dd*hEnVN#MpLM^q z$CiJp+LuJ{Vi!JbFg|ruz!+=HYK%M6SG~HcqI=a;1g^x(vD*}ei|zU}LQ58tI3buF zfJov4&V>+2J(2@^WQ0s2gO$vw51Ht$O!q*`flG)EagCI@&KSx+&M2>54u)RHz4H!Ipbo zkfQwQe@S9ul{kXibU9SP*{;P;VMU3&3!|gt>oi!Km#{ii=)P$`^6;`(xc)ALN-@#4 z*82WoCb~>N8o6yGg~>hx8*h)VSuy-P<%(V$iU@w<$U~_-aH zerJKd1Uto^hDIMqGJz>rlBmFABJobf;!r)5`^Q6Q_wD2Bvv31_(E#LL?=f^k0TNxA zRL}M@0%0yDkK9UOtz@;)ua(W7YVEC?G|4lWw^~#%AqOkBCQI8BWdQsg| zB?vY@ox6Q+StXq^Npe&wW7?#Z|wy)jbLmh)BTHjhjK*Hm;)gRU|pCTZQ0HJ7W+!nD&S_?--?u9lo|V03f`O>;gs~@xISn|%GIkd zpW9G--}-g^rM`mwjfR-8th9gGT93p`J;|bI)R^F%wxu(T`b2OT`K8=GM9sgC%a>NU zSe;~y6eIvlWmq8KoSbV**)=t625|R1(Z#2a^iH$ExE^yxg|)G-;2wTU6d&krR4LJFBZNV z;w$scPqMcFEyK5A7ruRMPK1rrzs~^B7t2+Rh{-7=fPwo{Utpmvr%daK=rQ=Bzw=L| z9;ZOt8|3dqekQ?)OXNAd)j71#D!)H#Lx0s0jgoG{P2k3ATD<+;X@_f7L+n$RBlj!n zTb>yd8gYUm#8tOA1Nav-4=V@Pi_hjT;w+mFRDjxLDxX=T-g`84(5HeX79Uog3Ty5X z796>s4fV;#^Nw=9Z#3e-)Q8s%d*h;v#B+wa;_V0J7e&#diun^b(vs#T8(tJg^x2W2 zCdFbBy}(s3ur&Y8$iLBrtp7!I{iiNu{g+Y$u>MQ*0a*X}+5bxqvi(cU{crUk)Bl|t z`>X!`6WGAS_FbDgK}@!8{9H!;#X%^yB*33aD5DCXvjGZCp?k1?=|ZcsT}x!4_86+iiH^G0(1+ z@B3#&q4BSj7I!aYi6AdJ7&Fp+Aq=~;;hDz6g~wXE-rl#P%cW~I5Q00Q;8?lz0gKUW z)#1IbvtvDv`k{$y*lCs1D8zzuA0m$XnxV^zm)o;#adLPgs+lJ0g<=AW`I+97!Ca6^ z#}cI6ait;OUi*S_ijlk@Ke_yVGLN`~h<4tw)EL6tPtq-5@w%|^xT<(BDnf-Y3Fp~{ zw9HmLn2SSBMc)i(H#RuetNCJG`!Jn694edA(uQ?zs3$ecj||L*oB4S8sO`aP^=DaX+VzL0QX{o)i+gv4QP{B2dv3?#E&5y7IYQCYm6DOxHd~fU zXur~rqqeK`w0+#NDxc-u>t&}?o)r}O-SI~NZzAI$*rkI2Q*MSIeYctZk+%9#XRKXq zy|J}=5Eks3m=~S7m*LOLvlZ<*(Ff=J_fZ$&OihM;Bf_YM#y9v}-aH>D#9KV`;4qyi zPJ10bdL=I$m!*%daO^CT#?DlP>{y!BD$K`B99NrW635V^u!`!dbDd37iPCIC6vw3S z)-kA5Q>k#_guF5=YrI^@9OKYb5Mtxswhei4w++{~CZ=#xEGy|;;d`+t zPVn81WaXe>tE44#5fIN)9a};NXa@{qx$|CPA9URwm}R=#s*7(ut2}>eBTqz7pWQ*5 z{x*xCaa@`dDKRk^zE{(x82e?L{a&|6E@4;=fbE7;R|4l&^bv?`H_qKrWf|_?R5+65 z(<36kNaO}j4JN5T1iq@9?888m4mz20k5AV%ziDY13p#GVK+?CB2mD^<3jLz{AV;1p=VH*;&n=C6HnF<3L1!g|tF$5BzuG3LC zvZg6PG(^G)l9H=7aNr@$=6E6lGH0WOUBrg`@HTN#gW1fV?hMD%MW~;&FOdS!#Ea0Z z`hl3|W3`L507OLL2ojo)UT6;!nGB{E>H=H{>s^ z8!u(4Xlv^21IA}5ih44zcD8PfF{+S@PIdWh?@Z_0k<}ap=@@IWBqmq?>^5~=`9#It z{_YU&n$shHPAP;W7GQr?O-_GeiMI6d@KU!QyJX~C$i zt>Eq=Y+hnZ=H-|gFZKz`&2wZuo>6UuAh|4jrT$cRS!Q7dW&sgtz4eHj8*u%z`F7Tp zPi|Xbo3u5&%qh6M!EEOl+D$pcA0U-)>k1}@Dzq?bHb|jxvySw3Y-mxJ2+JQ&Jq#|H zvIk&LRnNgltBoB%CV6uXnCBb8q}zk`bS63zu+jph%k)GBrdfLzVDE`bMB!7nVXwa| zShEE^5jnp?0D69+@8K{EDprK@MHCqHz!J?~J4#zNMrhD)sS9K>olmpAZ!S{N3?@oTs5waVPYz14**{FVXZtso*TMv(RjzXAA(hk2`3mfnvdOHJ*q-F-< zz?x%wvHA;RSVKUYx#k_WBUwWL`Z>B8(K8p)&56b-oa`G$fv1&iYJ=naM)P++zeGMd zQhet^LjmI4ATXNQz^hX-*wM_1*<2g``Ixe49wSHJZlaOTXM2*$!^A4+k0xVMau1%G zUDgT1@KF_l#^Sd#uB*JCXgrg9fA$`9oXDd7YU!m^{Vnh^}8J~D{C#2)ln!} zoFqqmiw5hCsE^)9v-8~_Lc}d@lPuQG40ER~or|e8*Ggx(SFKq~@BWsjyX1%reg5* z9Vau)i-cvL&ILu7ryU3B=9v_!H3$iQeYTtK7OE)Hhy0>7l+vR-R;SWENokV(H^*vM-v1hwHYd}0WA?$+2Bl5FF_~SuDa`4b%y-jt?GQEJJL>;TJ={nr8uN& znW~wgRdmuC4T52nrqIpO;gWi1JZbh2pHrLOHz!1pHeF>RS`z&dlOx84t%pU6eyY!!;;Y5m#fK}Z>>O}*UA%BpbZ>M)dXy@m}H#HpkHqK!Ls z=qRDs3uS6NFH4jqItYH(nPdFK3JKaPHkVxF%+%*#g@%G>oaS?B-UEG>o{Dar&*5Gp zHm@r$yU;U5yurqsQOI9Pf+BNr>tvMVrWM0&lxp*)Qbior>q5tBC}WjpI)qS;$JvNjUS=@5j0cK)lw;20!PBxaCB=RrBmv29G=E=+ zOOf+prKGJvYh_k}GOyq|D>|;m*e}qi(3zH22&AO;oQL85EC@|5MAg3A`J1rysR(7GfAGM@}zg(U2W?n?2n{hC!Fj1mWG7%!J`+5v0Y!@N_qQbI>p8pL~ zkLkZ|`1pT>923*O26;?O{}OaeO#f0`|821M4^#U819

9RT#VV)`zi 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

i*SUSkw=3S+ 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

>o|z4F#SvXV0t#Q?HP|H}87DU{eZkfe8=D6~nf) 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 literal 0 HcmV?d00001 diff --git a/docs/whitepaper/main.tex b/docs/whitepaper/main.tex new file mode 100644 index 0000000..b7b443f --- /dev/null +++ b/docs/whitepaper/main.tex @@ -0,0 +1,390 @@ +\documentclass{article} + +% Encoding and Geometry +\usepackage[utf8]{inputenc} +\usepackage[a4paper, margin=1in]{geometry} % Standard 1-inch margins for better layout +\usepackage{parskip} + +% Math Packages +\usepackage{amsmath, amsfonts, mathtools} + +% Graphics and Figures +\usepackage{graphicx} +\usepackage{caption} +\usepackage{subcaption} +\usepackage{multirow} +\usepackage{tikz} +\usetikzlibrary{positioning} % Ensures compatibility with Overleaf + +% Hyperlinks +\usepackage[colorlinks=true, linkcolor=blue, urlcolor=blue]{hyperref} % Load last to avoid conflicts + +% Floating Objects Placement +\usepackage[section]{placeins} + +% Bibliography +\usepackage[ + backend=biber, + style=alphabetic, + sorting=ynt +]{biblatex} +\addbibresource{references.bib} + +% Title Information +\title{EulerSwap White Paper} +\author{Euler Labs} +\date{February 2025} + +\begin{document} + +\maketitle + +\begin{abstract} +EulerSwap is an automated market maker (AMM) that integrates with Euler credit vaults to provide deeper liquidity for swaps. When a user initiates a swap, a smart contract called an EulerSwap borrows the required output token using the input token as collateral. This model enables up to 40x the liquidity depth of traditional AMMs by making idle assets in Euler more efficient. Unlike traditional AMMs, which often fragment liquidity across multiple pools, EulerSwap further increases capital efficiency by allowing a single, cross-collateralised credit vault to support multiple asset pairs at once. At its core, EulerSwap uses a flexible AMM curve to optimise swap pricing, ensuring deep liquidity while maintaining market balance. By combining just-in-time liquidity, shared liquidity across pools, and customisable AMM mechanics, EulerSwap reduces inefficiencies in liquidity provision, offering deeper markets, lower costs, and greater control for liquidity providers. +\end{abstract} + +\section{Introduction} + +EulerSwap is an automated market maker (AMM) that leverages Euler credit vaults for the provision of just-in-time liquidity as a way to provide deeper liquidity for swaps. EulerSwap differs from traditional AMMs in that it does not depend on many small liquidity providers (LPs) pooling their liquidity inside a single contract. Instead, each EulerSwap instance has a single LP -- an account holder on Euler -- whose deposits function as both liquidity for swaps and as margin collateral for building leveraged positions inside Euler. + +When a user initiates a swap, EulerSwap dynamically borrows the required `out token' using the `in token' and the LP's initial margin collateral as backing. This borrowing approach ensures liquidity is provided just-in-time, only when needed, maximising capital efficiency. By borrowing liquidity to service swaps in this way, EulerSwap can turn \$1M initial liquidity into the equivalent of a \$40m deep liquidity pool on a traditional AMM (see Example below). + +The way this works under the hood is by taking advantage of the `operator' functionality of the Ethereum Vault Connector (EVC), which provides a way for Euler credit vault users to delegate authority to someone else to manage their account balances. An EulerSwap operator is a smart contract that manages an LP's account on their behalf using the logic encoded in a custom-built AMM smart contract. Specifically, an EulerSwap operator is able to rebalance the collateral and debt inside an LPs account in order to service swaps and earn swap fees. + +Unlike conventional AMMs, which usually require separate liquidity pools for each asset pair, EulerSwap further increases capital efficiency by enabling the use of a single, cross-collateralised credit vault to support multiple asset pairs at once. This liquidity-sharing model ensures that idle liquidity can be used efficiently across multiple trading pairs simultaneously. This design resembles Curve's 3pool concept, but extends it to any number of asset pairings. Unlike traditional AMMs that silo liquidity into separate pools, EulerSwap's cross-collateralisation allows a single USDC credit vault to back multiple trading pairs simultaneously, maximising liquidity utilisation. A single USDC credit vault could be used to support swaps with USDT, USDE, DAI, and many other pairs all in the same block. + +EulerSwap introduces a flexible AMM curve (illustrated in Figure \ref{fig:fig1}) that supports deep liquidity for short-term swaps while maintaining a neutral net position over longer periods. A highly customisable curve allows for bespoke pricing strategies, asymmetric liquidity deposits, and single-sided liquidity concentration—all fully controlled by the LP. LPs can modify their EulerSwap parameters at any time by simply swapping out the operator smart contract in their Euler account for another one. + +For end-users, EulerSwap offers a seamless, Uniswap-style experience, while behind the scenes, it harnesses advanced features such as dynamic liquidity borrowing, custom pricing curves, and shared liquidity provisioning. Liquidity providers, including professional market makers, token issuers, and DAOs, gain unprecedented capital efficiency. Meanwhile, swappers—ranging from leverage traders and aggregators to MEV bots—benefit from deeper liquidity and optimised trade execution. + +\section{Example} + +Suppose that Euler allows borrowing of USDT with USDC as collateral at a loan-to-value (LTV) ratio of 0.95, and vice versa. This means that for every \$1 of USDC or USDT collateral, a user can borrow up to \$0.95 of the other asset. + +Now suppose you have an account on Euler with 1M USDC deposited as initial liquidity. Using maximum leverage your account could hypothetically support deposits of 20M USDC and debts of 19M USDT. Alternatively, if you swapped your 1 million USDC to 1 million USDT, it could support the opposite. + +To enable swaps and earn additional yield, you install an EulerSwap operator on your account to facilitate swaps. Now let’s say another user wants to swap 10M USDC for USDT. The steps are as follows: + +\begin{enumerate} + \item The swapper sends 10M USDC to your EulerSwap operator as the swap input amount. + \item The operator deposits the 10M USDC as collateral in Euler. + \item The operator then borrows approximately 10M USDT against the account's collateral, which includes your original deposit, alongside the swap input. + \item The operator sends the borrowed USDT to the user as the swap output. +\end{enumerate} + +\quad +Importantly, this isn’t a 1:1 swap because: a) the EulerSwap operator charges a fee for facilitating the swap; and b) the exact swap output is determined by an AMM curve inside the operator, chosen by you, which factors in increasingly large price impact as the swap input amount increases. After the swap, your Euler account now holds 11M USDC deposits and 10M USDT debt. Later, when a swap occurs in the reverse direction, the incoming `in token' repays the outstanding loan, and any excess collateral is returned as the `out token.' + +The AMM curve inside the operator helps to ensure that imbalances in collateral and debt on the account encourage swaps that bring your account back to neutrality. The AMM is designed to help ensure that positions on your account do not remain open for extended periods, reducing your account's exposure to borrowing costs. Over time, your account will incur costs due to small interest rate differentials, whilst generating significant swap fees through utilisation of idle liquidity in Euler's credit vaults. The whole process is depicted in Fig. \ref{fig:EulerSwap_liquidity}. + +\bigskip +\begin{figure}[h] + \centering + \begin{tikzpicture}[ + node distance=1cm, + every node/.style={draw, text width=2.5cm, align=center, rounded corners} + ] + % Nodes + \node (user1) {User Sends 10M USDC}; + \node (EulerSwap) [right=of user1] {EulerSwap Swap Operator}; + \node (deposit) [below=of EulerSwap] {Deposits 10M USDC as Collateral}; + \node (borrow) [below=of deposit] {Borrows ~10M USDT}; + \node (user2) [left=of borrow] {User Receives 10M USDT}; + + % Arrows + \draw[->] (user1) -- (EulerSwap); + \draw[->] (EulerSwap) -- (deposit); + \draw[->] (deposit) -- (borrow); + \draw[->] (borrow) -- (user2); + \end{tikzpicture} + \caption{\textbf{Swap flow in EulerSwap AMM}. EulerSwap’s just-in-time liquidity borrowing. The swap operator dynamically increases liquidity by borrowing the ``out token" against the ``in token."} + \label{fig:EulerSwap_liquidity} +\end{figure} + +\section{Virtual reserves and debt limits} + +Since EulerSwap AMMs do not hold the assets used to service swaps at all times, they do swap calculations based on `virtual' reserves and debt limits, rather than on `real' reserves. + +Each EulerSwap LP can configure independent virtual reserve levels. These reserves define the maximum debt exposure an AMM will take on. For instance, if a user deposits \$1,000 in collateral and sets virtual reserves at \$5,000 per vault, the AMM effectively supports up to \$10,000 in combined swap depth, with a loan-to-value (LTV) ratio of 83.3\%. + +Note that the effective LTV must always remain below the borrowing LTV of the credit vault to prevent liquidation. Additionally, different AMM curves influence whether the maximum virtual reserves are achievable. + +\section{Curve} + +The space of possible reserves in an EulerSwap AMM is determined by how much debt a swap operator is allowed to hold. The EulerSwap curve passes through an equilibrium point $(x_0, y_0)$, at which the marginal price is defined by: + +\begin{equation} +\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}. +\end{equation} + +Unlike most AMM curves, which are usually defined by a single convex function, EulerSwap uses a piecewise-defined curve, with different functions providing trading behaviour either side of the equilibrium point: + +\begin{equation} + \label{eq:fx-main} + f(x) = + \begin{dcases} + f_1(x), + & 0 < x \leq x_0 \\ + f_2(x), + & x_0 < x + \end{dcases}. +\end{equation} + +In the domain $0 < x \leq x_0$, the curve is defined by + +\begin{equation} + \label{eq:fx1-main} + f_1(x) + = + y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-x\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{x}\right)\right). +\end{equation} + +In the domain $x_0 < x$, the curve is defined by + +\begin{equation} + \label{eq:fx2-main} + f_2(x) + = + \frac{ + \sqrt{ + \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right)^2 + + 4c_y (1 - c_y) y_0^2 + } + - \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right) + }{2c_y}. +\end{equation} + + The $c_x, c_y$ parameters here are liquidity concentration parameters that control how liquidity is distributed along the curve, with values closer to 1 concentrating liquidity around equilibrium and values closer to 0 distributing it across a wider price range. This flexibility enables EulerSwap to be used for entirely new use cases or to simulate the behaviour of atypical AMM protocols, such as the MakerDAO \href{https://mips.makerdao.com/mips/details/MIP29}{Peg Stability Module} (PSM). A full derivation is given in the Appendix \ref{sec:appendix}. + + \begin{figure}[h] % 'h' places it here, 't' for top, 'b' for bottom, 'p' for separate page + \centering % Centers the image + \includegraphics[width=0.5\textwidth]{curve.png} % Adjust width as needed + \caption{\textbf{EulerSwap AMM curve.} The EulerSwap curve (red line) consists of two sides with separate reserve values $x_0, y_0$ and liquidity concentration parameters $c_x, c_y$, allowing liquidity to be distributed asymmetrically. This means liquidity can be more or less dense or concentrated on one side of the AMM relative to the other. The exchange rate at equilibrium is determined by the pricing parameters $p_x, p_y$ and is fully flexible. You can interact with the curve \href{https://www.desmos.com/calculator/gzwmvbs1dk}{here} on Desmos to compare its behaviour with traditional constant-sum and constant-product curves (black lines).} + \label{fig:fig1} % Useful for referencing the figure in text +\end{figure} + +\section{Conclusion} + +EulerSwap enhances AMMs by leveraging just-in-time liquidity to expand the depth of liquidity available to swappers. By integrating Euler’s credit vaults, it enables LPs to earn swap fees on top of their ordinary deposits while offering a customisable AMM curve that supports concentrated, distributed, and asymmetric liquidity structures. These features make EulerSwap adaptable to a wide range of trading strategies. However, this efficiency is not without some trade-offs. Swap operators incur interest costs on borrowed assets, which can erode profitability if not offset by swap fees, interest on collateral, or token incentives. Additionally, EulerSwap inherits Euler’s risk parameters, making it most effective for correlated asset pairs with high loan-to-value (LTV) ratios, while volatile assets pose higher liquidation risks if positions become imbalanced. Despite these trade-offs, EulerSwap represents a breakthrough in AMM design by repurposing idle liquidity in lending protocols, reducing capital inefficiencies, and optimising swap execution. By catering to professional market makers, DAOs, and algorithmic traders, it positions itself as a powerful tool for on-chain liquidity optimisation. Future research could explore optimal strategies for setting pricing and liquidity concentration parameters dynamically based on market conditions. EulerSwap's design opens new possibilities for AMM efficiency, setting a foundation for further DeFi innovation. + +\section*{Acknowledgments} + +During a security review of EulerSwap, Chris Michel noted similarities between some of its underlying concepts and BlackHoleSwap, a project prototype he had reviewed years earlier. While EulerSwap was designed independently and without influence from that project, the resemblance is significant enough to warrant its recognition here as prior art. + +\newpage +\section{Appendix} +\label{sec:appendix} + +\subsection{Curve derivation} +\label{sec:curve-derivation} + +We begin with an Automated Market Maker (AMM) holding initial liquidity reserves of two assets, $X$ and $Y$, denoted as $x_0$ and $y_0$, respectively. In the absence of trading, the AMM remains at equilibrium at the point $(x_0, y_0)$. + +Our goal is to derive a curve for a constant-function trading market maker (CFMM) that supports swaps between the two assets with the following properties: + +\begin{itemize} + \item Passes through the equilibrium point $(x_0, y_0)$. + \item Maintains an exchange rate, given by the slope of the AMM curve, of $-p_x / p_y$ at $(x_0, y_0)$. + \item Allows liquidity concentration to be adjusted via parameters $c_x$ and $c_y$, which control the liquidity available for swaps to the left and right of the equilibrium point. +\end{itemize} + +To develop such a function, we first introduce two fundamental AMM curve models. + +\subsubsection{Constant-sum and constant-product AMM curves} + +The canonical constant-sum (CSMM) and constant-product (CPMM) market making curves are given by: + +\begin{align} + x + y &= x_0 + y_0, \\ + xy &= x_0 y_0. +\end{align} + +The CSMM is simply a line, whilst the CPMM is a hyperbola. These curves can be thought of as two extremes when it comes to the distribution of liquidity. The CSMM concentrates liquidity at a single exchange rate, whilst the CPMM distributes liquidity across a wide range of different exchange rates. By default, these curves intersect at the equilbirium point $(x_0, y_0)$, where their slopes are: + +\begin{align} + \frac{dy}{dx} &= -1, \\ + \frac{dy}{dx} &= -\frac{y}{x}. +\end{align} + +Since real-world markets often operate at variable exchange rates at equilibrium, we introduce custom pricing parameters $p_x$ and $p_y$ to allow flexibility in defining the slope at the equilibrium point: + +\begin{align} + \label{eq:weighted-line} + p_x x + p_y y &= p_x x_0 + p_y y_0, \\ + \label{eq:exponential-form} + x^{p_y y_0} y^{p_x x_0} &= x_0^{p_y y_0} y_0^{p_x x_0}. +\end{align} + +The CSMM is now a line with a slope parameterised by the ratio of the pricing parameters, whilst the CPMM is now a \textit{weighted} hyperbola. Taking the derivatives of these equations with respect to $x$, we obtain: + +\begin{align} + \frac{dy}{dx} &= -\frac{p_x}{p_y}, \\ + \frac{dy}{dx} &= -\frac{p_x}{p_y} \frac{x_0 y}{y_0 x}. +\end{align} + +These results confirm that at equilibrium $(x_0, y_0)$, the slope of both functions is: + +\[ +\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}. +\] + +Whilst these curves sufficiently generalise the constant-sum and constant-product curves to an arbitrary price at equilibrium, in practice, the modified CPMM equation \eqref{eq:exponential-form} has limited practical application as a CFMM because it involves an exponential form that is computationally intensive and impractical for on-chain calculations. We therefore seek a simpler equation that preserves the spirit of the trading behaviour of the generalised CPMM; that is, some kind of herpbola that passes through the equilibrium point $(x_0, y_0)$ and maintains an exchange rate of $-p_x / p_y$ at that point. To resolve this, we introduce the concept of artificial reserves. + +\subsubsection{Introducing artificial reserves to create a new, simpler curve} + +Note that in the interval $0 < x < x_0$ swaps should only increase liquidity beyond $y_0$ and deplete $x_0$ liquidity. That is, our trading function in this interval need not depend on the initial amount of $y_0$ liquidity. This suggests that we can split the domain of the AMM curves into two, and replace the real reserve $y_0$ in the interval $0 < x < x_0$ with an carefully chosen artificial reserve $y_v$ designed to eliminate the exponential form in the weighted hyperbola. + +Re-arranging equations \eqref{eq:weighted-line} and \eqref{eq:exponential-form} into explicit functions of $y$, we obtain +\begin{align} + \label{eq:weighted-line-explicit} + y &= y_0 + \frac{p_x}{ p_y} (x_0 - x), \\ + \label{eq:exponential-form-explicit} + y &= y_0 \left( \frac{x_0}{x} \right)^{\frac{p_y y_0}{p_x x_0}}. +\end{align} + +In this view, it is easy to see that a substitution of $y_0 \rightarrow y_v$, given by + +\[ +y_v = x_0 \frac{p_x}{p_y}. +\] + +will eliminate the exponential form in equation \eqref{eq:exponential-form-explicit}. We then have equations + +\begin{align} + y &= \frac{p_x}{p_y} (2x_0 - x), \\ + y &= \frac{p_x}{p_y} \frac{x_0^2}{x}. +\end{align} + +Note that simply shifting the curve up or down does not impact the slope or shapes of the curves and therefore has no impact on trading behaviour. Since these curves no longer pass through \( (x_0, y_0) \), we therefore correct them by adding back the difference \( y_0 - p_x / p_y x_0 \). This leads to: + +\begin{align} + y &= y_0 + \frac{p_x}{p_y} (x_0 - x), \\ + y &= y_0 + \frac{p_x}{p_y} (x_0 - x) \left( \frac{x_0}{x} \right). +\end{align} + +Taking the derivatives of these equations with respect to $x$, we obtain: + +\begin{align} + \frac{dy}{dx} &= -\frac{p_x}{p_y}, \\ + \frac{dy}{dx} &= -\frac{p_x}{p_y} \left( \frac{x_0}{x} + \frac{x_0(x_0 - x)}{x^2} \right). +\end{align} + +These results confirm that at equilibrium $(x_0, y_0)$, the slope of both functions is: + +\[ +\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}. +\] + +\subsubsection{Unifying into a single curve in the region $0 < x < x_0$} + +To create a single unified curve, we introduce a liquidity concentration parameter \( c_x \in [0, 1] \), which determines the curve’s behaviour: + +\begin{itemize} + \item When \( c_x = 1 \), the AMM functions as a constant-sum AMM. + \item When \( c_x = 0 \), the AMM behaves as a constant-product-like AMM. + \item Intermediate values of \( c_x \) create a hybrid trading function with liquidity that is more or less concentrated around the equilibrium point. +\end{itemize} + +This gives the final equation: + +\begin{equation} + \label{eq:EulerSwap-1} + y = y_0 + \frac{p_x}{p_y} (x_0 - x) \left( c_x + (1 - c_x) \left(\frac{x_0}{x}\right) \right). +\end{equation} + +This is equivalent to the function \( f_1(x) \) given by equation \eqref{eq:fx1-main} in the main text. + +\subsubsection{Extending the curve to the $x > x_0$ region} + +It is important to remember that equation \eqref{eq:EulerSwap-1} only works as a trading function in the interval $0 < x < x_0$. For \( x > x_0 \), we construct a reflected curve that also passes through \( (x_0, y_0) \) and maintains the required derivative: + +\begin{equation} + \label{eq:EulerSwap-3-inverse} + x = x_0 + \frac{p_y}{p_x} (y_0 - y) \left( c_y + (1 - c_y) \left(\frac{y_0}{y}\right) \right). +\end{equation} + +Since this equation defines \( x \) in terms of \( y \), we invert it by solving for \( y \), leading to the quadratic equation: + +\begin{equation} + y = c_y y^2 + \left( \frac{p_x}{p_y} (x - x_0) - y_0(2c_y - 1) \right)y - (1 - c_y) y_0^2. +\end{equation} + +Taking only the positive real root, we obtain: + +\begin{equation} + \label{eq:EulerSwap-2} + y = \frac{ + \sqrt{ + \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right)^2 + + 4c_y (1 - c_y) y_0^2 + } + - \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right) + }{2c_y}. +\end{equation} + +This corresponds to the function \( f_2(x) \) given by equation \eqref{eq:fx2-main} in the main text. + +\subsection{Invariant derivation} +\label{sec:invariant-derivation} + +In traditional AMM protocols, the curve is typically defined as an implicit function of $y$. For example, the classic Uniswap AMM follows a constant-product equation: + +\begin{equation} + xy = x_0 y_0 +\end{equation} + +where $x_0$ and $y_0$ are the initial liquidity reserves. This equation defines an invariant condition, ensuring that any valid swap must satisfy: + +\begin{equation} + xy \geq x_0 y_0. +\end{equation} + +This condition guarantees that after any trade, the product of the new reserves remains at least as large as the initial product, ensuring that swaps cannot drain liquidity from the pool. + +Rearranging this condition, we can express the invariant as a lower bound for $y$: + +\begin{equation} + y \geq \frac{x_0 y_0}{x}. +\end{equation} + +This means that for any valid trade, the resulting reserve state must lie on or above the AMM curve. + +\subsubsection{Extending the invariant to EulerSwap} + +For EulerSwap, we apply a similar principle. Given any reserve state $(x, y)$, we check whether it satisfies an equivalent invariant condition. + +From equation \eqref{eq:EulerSwap-1}, for values where \( 0 < x < x_0 \), the AMM curve constraint requires: + +\begin{equation} + \label{eq:invariant-x1} + y \geq y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-x\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{x}\right)\right). +\end{equation} + +For values where \( x > x_0 \), we could derive a similar condition for $y$ from equation \eqref{eq:EulerSwap-2}. However, a simpler and computationally cheaper approach is to use the inverse equation \eqref{eq:EulerSwap-3-inverse}, which defines the lower bound for $x$ instead: + +\begin{equation} + \label{eq:invariant-x2} + x \geq x_{0}+\frac{p_{y}}{p_{x}}\left(y_{0}-y\right)\left(c_{y}+\left(1-c_{y}\right)\left(\frac{y_{0}}{y}\right)\right). +\end{equation} + +These conditions together define the valid liquidity states in EulerSwap, ensuring that the AMM remains balanced while allowing for greater flexibility in liquidity provisioning. + +\section{Disclaimer} + +This paper is for general information purposes only. It does not constitute investment +advice or a recommendation or solicitation to buy or sell any investment and should not +be used in the evaluation of the merits of making any investment decision. It should not +be relied upon for accounting, legal or tax advice or investment recommendations. This +paper reflects current opinions of the authors and is not made on behalf of Euler Labs or its +affiliates and does not necessarily reflect the opinions of Euler Labs, its affiliates or individuals +associated with Euler Labs. The opinions reflected herein are subject to change without being +updated. + +\end{document} + + + +Section 5.1.2 starts off with the principle that the trading function should not depend on y0, and applies it to formula (8), on the assumption (correct me if I'm wrong) that whatever y_v we choose will not change the trading behaviour. However this is not true for formula (8), because y0 is not just a vertical offset, but is embedded in the exponents. +What stays true is just the fact that, whatever y_v we choose, the curve will pass through the point (x0, y_v) with slope -px/py, so we might as well choose an "easy" one that simplifies the calculations: the driving reason for imposing px x0 = py yv seems rather to be that this renders the exponents in formula (8) equal, thus effectively reverting it to an unweighted hyperbola. Then, once we add back the vertical offset, the trading behaviour of formula (14) indeed no longer depends on y0, but just because we have now "made" y0 just a vertical offset, shifting formula (12). +In other words, we have formula (8) which defines a parametric curve y = f(x; x*,y*,p*) that always passes through the point (x*,y*) with slope -p*. We want a function that passes through (x0,y0) with slope -p0. We could use y = f(x; x0,y0,p0) but this is computationally intensive. Instead, we choose y = f(x; x0,x0p0,p0) + (y0 - x0p0) because this still satisfies the requirements, but the particular choice of y* makes f() less computationally intensive. +In fact, there is a mistake earlier on in the appendix: the slope of the plain hyperbola x y = x0 y0 at the point (x0, y0) is not -1 but -y0/x0. The choice of y_v = x0 px/py makes that slope equal to -px/py. So overall it would seem like choosing a plain hyperbola from the start, with appropriate parameters and offset, would do the trick. Have I interpreted correctly the intentions of your derivation process? \ No newline at end of file From 8538a3bbe4ce526a32b3d5da08acb1fb35c29a48 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 2 Mar 2025 12:24:37 +0000 Subject: [PATCH 152/312] fix: remove old white-paper dir --- docs/white-paper/.DS_Store | Bin 6148 -> 0 bytes docs/white-paper/EulerSwap_White_Paper.pdf | Bin 357912 -> 0 bytes docs/white-paper/curve.png | Bin 262544 -> 0 bytes docs/white-paper/main.tex | 381 --------------------- docs/white-paper/references.bib | 91 ----- 5 files changed, 472 deletions(-) delete mode 100644 docs/white-paper/.DS_Store delete mode 100644 docs/white-paper/EulerSwap_White_Paper.pdf delete mode 100644 docs/white-paper/curve.png delete mode 100644 docs/white-paper/main.tex delete mode 100644 docs/white-paper/references.bib diff --git a/docs/white-paper/.DS_Store b/docs/white-paper/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T02!X13eR%*^)mch5aD_q}-<>hX+6}V`*z@=xFI_ zY64*VI|DGYvU4&r0q7+F+5jd-7A62Q3nM@mKratqWdYEO0ysGt8Q1{yasW;My~;n{ z%q+|RK0X*zTa$l60{&n8z_2p@mlsj-ur~$JYbcqT{e2BnTXSa%04E24Ud+|hDq?DEXY$wUU!#Jdqm2{b9}tA?tX*tuodB!=dId*Q6H8-fJ4e7@6!`c6^y+_s zU<5G#{r*Kk($>V({jcFKgiMV8X)&_{u>6Cl5`bRG&dwRY%Ji>^@?TH^Ol*Hq{TtKu zUr@39&+yPoiU72EI5|yC*^D@t8QEBw8H^b@3|ZKjOgT9?j2M`Vn3$Lt_;@%un2lMD z7#U3rIoVA(IgN}M%@`RBnK+G2nT(AX8Cdyr|4D+Av!kh@4UBu1v5|?vj=6!6fdL0J z@#?A|sWERF9C+d{0n!<6q#t&0#Hu0!MN}Hgx1ixB%b@Wz9R_THCQW6a^~M8z#BWfV z@n{g_!{60h242`$;$w;lT%`M50d517oNbao7?kjm|D^jrANK!2;{Rt5|9k%52>dq! z|Bb-^KM{cW55oC3pUWBAm^uMiIRC{#^7f{-g2v94cD8@{iupfnF3#3}N#6;;$o8L1 zrC?}oD*GSAsOn@Y|L@E6|Cs;r`iEuzlH0!sR@l(l(Av)YzfeBwKXL#4`2Qu{Dgzif z{!+0#fQjQDjqxvXX8Nlq{s+o3F!;+?JK@F#h6V;3V}L;*a051KP~5n&I{|2k;T{_f z{Tl^&H}JUbhoC2nt8X}doU~;wGH~@jJiGHY_l&4~$91HX238u@nes=j+v9|h0uJiQ z)E(vQ@Tr?W+Q0ga<}}MBP96rwl-fs#euD94*9^6Y9_q!|q2%QKVB$15e@HTJgry&0 z=gELdisWR&EyJw56lkFY{q=?epamL~G6Kc>TH0+g?rLSeH+&4;b5Z5LXrt~SXyA0Puom{P z`+!NaA%RLZO|<^+bov*Z{|i(>TU$G4r+*2u|HuUsBkO;TZ2vj3|Ht@Op$OaAI-A=5 z^=AE-3%%@LJ!2?j_m67%N2RcGveGfJvjI3*80k1T|IsvmWzgRn{tCPQ2tlu8>SX8Q zX#6+xOpF}=GW{#_|NI>OYuf*b|Nofwev{|F*1Ng|=9aSbZsy{= z!$lMCqokZqB25CFy`)YAt7rw7a9_`xVP}&rGCj`}#3wF6p?Nq@Ivg%X%2q0VC;P&m+(`>7B0q+K(y%tTi<9?x{GxZS zv=BQ!?>>rz)BQP0b0;oD-do?2!>YvF@vO|brr$<>h=pB0t<}3nPYyD!0LBG|%T`Gj zQWnm*A#JGL{>!ec_ro4h=nYH^%G@2B18lOtcaCdpOmYX2z!kJNqhz<|##unUT)75u z$=B`;5GdB?Y?J5NzB6%TNG0ii+g9Ye$%V=fMyh5yS%nChsX*}hJ_~MltXQBORxd}) zHEHu{mz7dIs_-)U5WW6LJ3$36N?h(qdGvU-S!$)dvS6^;KPd^vm7-)IE5L^~y-@9Q z=9@?fRitF+K5p(iuA1h_G_(Kx(^+a;HKhrcqJQ7vq;x>>WM7f2OW3Mz;q*+$Q@fWZ ziBlixszoNK)n{e(=LO_x0&@3zNXtVC+-b9dytRi{Jy&9$EW6~7@w^x%tIIcbfCcu*R2%7QD-yg45mnFf48hIwVC1^SFQ+8 zRZGhgP4()ZCx#X#*t|t^SO+psGT`Fow)Dg)i&czzX+2PI6h*{g84do`ef~*XbhkTDg$;(5ht8@0FJmW#^ zMe~X!tiEy~oC^9lSJxnzVie}dGoz4>%ZpaCPRv!orN#-qvBBm`xAnCgnJ|O66vLbCvFP=Z^*xy;ckIm!b%GsA&EQ0WDT8xX z0`gaPaUs_5@JZ(=YkWf2+@_YE%*|COILfKZ`b#LYPI#SxJD{RsW+lrS8 zWh`~}<0v!o@n^Ajk-Hyd4s{kA0Q#U!VF{x{hzMER*<)53E=a=OMzuoNFhIKMqgL-lsd3C@f9`t{_Mp zGhx6gfxykxD3;`8Gwn;Jp#p{Y;%sVYF*(w^P#3SZlZKu!1hK+Fp+)lb5VhdXYD%C! z!4FOvUZy0&A<9KT&lI#1(gN(>+33p9LtQlBQ=^gf=EgV&cD$?vnx1Z+hG|aaJdzgO zzwq=3ap51s1=cnW9G4X2rC-$#=3C|6Ce71fJG>L?RAVC;?U0GfYAuf8!TYfMmaDot zQbxhaZhl+~7-UQ^88%593{`>sTwW5)sK*p9-4wO0U#E!7BTF6DSoMB(vV`n4y{aR#z!qhv{a70P)2^kaI1jd)NfRql`H7_WDUVwQKu~$<`#)juz^Lc zu~haDWgwLUAtQ-_6H=$Z(ST!_FRF&PeWbs5 z#{g#+w|mE+-~~QNSCBzbcb`+%{C%wdB>>DV;n0^?OIARPPk=lqT%dyh_hS0>wwbwn zfk8p$stYsj0%C^?{Ab`fjGtHY1K2eaQkDaiDg&LVv_Cu_2$wu^OG3r*+Ii{(u*cC6#is9#KGu90$7 zq4!AMtqH!>KYHD!+)-)wOq(PMadleBMoArb$H9{@LB`8_C$;7Zwu+}4wnB`cWXS6x z)#^jWC$Hx1NZDkBC)|e!e=`j3pzqXgyxz^+2mdVaXYEU;*Qtu zoSlPs#coAmVS@32y2}RXCO`AQn>1NraGOh|jjEO$d=V>?mxHAQ)9A#_sLMXUgz7~p z_rc&eT?$U#qe6$0n^OQ)M$|)Xj5tD7R9@hlG@A|!jP{-`*k9!Y8vk1BjNP*6krJXiz#`rP3;%P zGt(c^nDNDXhpM)5xbPjUhNm)>b$cB7+kC=!#}u|Ikon6h+AT_R;QQFs(}$i9LukMJfcpE_EvDv>h9$pvMd zT#`pn3{Mzk6KOM=?C=6@P@&eL9*<+Udy|(B$BSS)Ev&LneJWdsb#qnjPNq=>QL;d4 zC_geWS>ak9>2tb%Fo}D#3v8FBE@^j3vB4fBh114eFE&2wKqiWFGuLPB<-gqXX z_ZX&uC4Uhy%Zzv+4D(QK_2pqFxt>_UYE?OV&&Sz^Tv5|#>=Kb-5)D5xMb0MkJ6}YQl5SS{tID=z{8&LjK zG(0SdExL%W+wm@$FvgCan2;HxXU=JGPszu*y`xDy9zs9(`dMElZNaOJLZibCyVHT& zT(-v52AgMuHaa1IWp8m%3OhtUE}=Hl21?dF>5pt_&2UE<@17-#3fbgcWxh_d`ir_K zRgbWDQ#9`eTkq}AxnaNW1iGoSHRS|Hp*mYddP~RfW4YhdYEEfM-&VpOjGF5)o-<4T zS%G9S#DVeHYR_``u$j)F(PMryj&L}BQ zb1V}}Jn&QrjI2EGlvHt4CSbKUz*}DDM4b;*Y2X^j?qq zWRV`a9c53DCcXx#W;vbv?mIk+tVh@Y{78X$zl4+NN3C5$-rL5{!hnkz*Jt8bHp}=e zzMPV`lP>oQ-GYLNApb9QVhI$Z4=cK6JKd(Xk^G`F9(9(P{iJ%igR9UCE}J5%pGht0 zKdB6y0|&!9}tMd8+3Z=MGsH1x7s{{-yny0Bjtb?EjwqQz!nr`eWx{{~yc0Xg5ffEZr5hxj>QH zIk6-pQ?cuA(P$i9IA*M2xI(vrRwS@F?m1Bk&uD-rR6(c+YyoPIT_r?W51R zp4FAprR&qy@tXPOz;IRd2nnR1mSA!`lsW;QUL1#jpz@Xk91sZfO`yOBn6>pAgF43p zJtOcsD&;tMs7UyCSO5qNjH~DbT7QiNw=5}0-Vp@k4K&b8@X)KspdbKiq#NYW&sNechXKww&3VNsR2<#>zBEtUL6>^kQNRh#c0VEIF zwK<5Zz^w^l0N7K)3TtucoRElv^ioGRdoVx%5fM?Zt`L?U#guw#4F1NyeGS+-pH3l( z8x7<|l|caZ0_sy4n;sZfU>o7+PP`_p$>9;GFb}8+2%#~QSZ9{N777XtT)+-tR(T1C z$2E}n3(M+*aR=gK2^WZve!F+z^YD`z3GQ|s+uA1D*%^eS%K%E-A07??oJVbW$K}!a z5W*ihPCwM34Ho4R(G_xF$AG%2|9Y|?$dnTw2upWI|FB)7&_J$+u8WT0r4}Wi_jg`r zRj@xL03SaeN*yy$|Mkaj1qCbT^=^MZxnPKUtR`-frw8+ zw)qDvf(-qNf#25E(G7#Z!av6_HcR|WFTOB=IlgcZm6iNHVG>Hl`7uv41{<%9&*xp}@9W;QXU{eHpu~H1O zvkMyVB^^dUV+Hvzv>Ql%V26&z%l^Hg1Z@}{{DH&ZOJoRy6$0XgoEM7~9Sp?heIgkw z!0V@s1#}<^(4C_La(3_q!X=H|S@D2@1@?FB73qyng93v3!i@m&SMwub1e$%@4v&>b z0uuRz6d7@NMWloS>i7!%9$j984-twzw`0qfe#QLqVHe2HQLqYZ$1Z9X3IEKDYc*eT zbSB`@7b_-T?ZGN>ynC6<43ceSbAdIS-3x$uzmS*e)2&%@L!5r%^yzLzaWe(Z|Tn@sZy`|CI^YiCE>CvnlyPX!97PICX_HmKp5|}^7e`i#Qea@8@QOeQM zbc}}f8Nkyy-5A0RBsI4As`vjevwl2gSE=Hos ze;jya$nO*^^t>jHb9cDQOLP!dD1@FZbs?M%2Z&^q-Ffw@!DP$m6FfrM_9n~H@L1Z2 z29g=(r&ktv?SG{pae*4rDKqEanol3}kKfH>GdGjE*TPuw-^On{Ye_6J@iJE^?Nt1K}ClbLS21SN+X0C^tIQ=HBa+Uw1Qwe!F zmO`f%f?dIN@^OAqRy#vx+!*4>72iY>s#^F7={)P&e$NzBxg}dI$i=y zEf{kDcY>#D9%--%ju73H>(V5+#`!ULTj{WuihK6mLa^Q`bG5@m##e+WBS%kC2EDi1 zRQMtI_<-4OegnBZcRgclTpv1*>lZ`V*3b{+1o*8vg5Tx-#Whj!7f;@H6$k|S#uxG~ zdgNo-H+LC6cGqA7!6C!HU9aCoouPe-kMBSYV<9{gCox4ULK~ORioTdjBfFg6iq|yf z+jAGWdA8afaOk)lHu~KJmyuYY~0*c&Hy`iBuRUQlnnS zo5Si8q9qE%z(v{L9ge^5&z++{z*o<`0+Kz4AmVgvly$Ds$J@Qkg-;if|F% z7d&0Aw$Q4Iix4cf|tz^SFHs2B-rUVdNX7d{TYt>jP zSRGN61qiLY6I7dV?=aKD8*wM;E3q+@sSrwAxVT9G`wx)76`qkOj)$ncAoMLmS72+R z7lsow7>4oW@rnxC@a5QGicqwkUON>0`WL0G@~%pWgr-akPXP^+KfDauMqBdKlpItO zAG2tp;>F4Nz0W6BLc$v_nO?aGrb8%IyGy&oNhu`k{s0pFuGU*wBzZcjsujYy?XS|u zov(ob4CUT5IVjR`ec3g*iv~z{0`TYHu=AWjf!<6FpH|n=jM_YluAuKA1IwvKPrLYX zO1!9~DU<|fIl&g9DMVRgpT3Oa4b^=>jVHr~iu>L=R0oMFn#JFV%U)n&kFUZhV4x5h zSA(AHGd!dsrwQ~HJXE{{yoWV)H`fky%*I-VG8M>JOqW58zo=eSr8I0I6Vtq@_D$SX zr8m-EMuQ)`sOMnfDC>kDr!``O{UHN3Ev-?hb9iUDi%h{S`ahH68P91K(5in|Rv~;( znQ_La5ri#yln$Sda_Mr@7*V_My#2}I$RJjDn!A@&!o*MdxfUAi;BVBCw@!=@>z=Z( zu{zQ!&-KFRQLnE|AcbJ*qn-_>^c(6(w1v30#fO~BJi==(PjP0166f1y4{|$TzQ>xj z)Hk{KV?G^To8%quK-i%TTy&(Jb@(^USVVSLTW>gd{Bd1S2?|MW@0!C|=zii$hF}@- zmgRa;&w&D~L|hs1VuAyeMCbR?iWd%44YYNb6y%}z{wR%r#OnpOVri7)Tp8D#J)S8# zufgbD6YO|gxcq5+(nG*}o8y``hVG~V$=>|YqgXBmt!uneZ)-F}X&+K?DXk0MHzu$g zNa;^9<2!llDJ`*6O-Z|hr)kGbQ+OBW9)yI=OKbLyc0is5D45Tk_nhOOo3@%D!F zSmQJW`1sQjDg9`vJ6vF4C$fkvO%2x+`6wG~+p+@;O-_1@4u7GwkVh82*=7~^YUmJY zva!X=(~uojf~e1g>EYIxBseB`!twO$rwwzk<%VkTpVh3Cot>wb9rzhO3*`~><6-I2 za`#62$h3-Z-)XUYd_18 zEWyyN#v5b)5G&xLc|jCPnMYoG%>I}Y4K0r4u5 zjqP*{Bsg4i!vTbu3#Z5B_)XL#h0#yLbAoALq#x!yVF>;3IsUp(@<4>H{7!KpWJ?BH zu<)jLv%;*!g>co}2_2Elh*NJB?6K?E?kc(RDPOC03L(9J=DgdICQLEhdSSFs)}Q!! z`{RHW-^R|+`ru_zog(XXDkcTHqtHB3J8}0Q7MyHtKr&iyJGwHKIQbH_NTa&>O0!A% zB}aFVo2sqG`m!?V_d>wqy|rxF!L)I^S5`+nNI)r^$C#G0Dc|TgpR|%^T|KbW78zSu z7^3v3DG|c()9^tMqh^TPk?kmS1KFIj>=Sk`1^0fDvT*$KFshMZ1#c?MSgPB*!k&zJdKC^_VHKAtHSzn)0$* z=9Nz?dx++AKZT&Ryg3?@Vz3#rPf)SC9QFiF@s)W-`qDx%(prT4$KbtN`MdS?X1>?w zyq?>1@H%s0z8f5C1x*D$$yh#~x5;b!1fgADoiQrZ>Q5DcNw}i6l9-=}xwCU_Phi2z zEvr!k8~UZRUjDP;iv9?D70?m&UZPWB0_F5H^V|G-y)~to9oDKg*g)x~?6jMWvvii& zJamOh`Z1k3NLoDST{Qnke>Da-shhTPyaih_%F=8`|( zz(wmek>iNn(Hnr2>?dOam+6-!N1V)%l4)&i1nvUhTht%*qaj^n+iia_pz;YXmVXW2 zT4W&&@lp;E&PP=%`ue+pdw1LZn7n7JB1oWK)-pYLa~L!4M-k6BiFRF+mRqj0TP2u3 zlGgXxQrpetRaNF@ew?cPLii$(FKXdbs{ow36Rd!Y(kb%vw{DEUW?jnY@JGF(;AgC2 zoe>EgxwsvoNV#yPl(^Ru({p4KthL_G7mLqdv$exF8oI^Vy&A8QdI> zO>+re5XmqBCFV@#`{p3slN&1gHbUKFp<9{z4c20&{m=wuTtNCAF>{bTHfW~zR^#24 z!M9Y#hj9CKai3ymGl+kg(o`!9-%UcdEtW4Oa};Nq2`g=3I_USLsbe;11-EF|>8%Xeki2^- z31(!9qi!4>*MPR%;d^|G`C-q>oG_4|_Zy>f5JLzGP*LqJ%PETQa4m9oMWOy7-x*Dv zM1?K!J{CfLquRw^Bb6b~soAHxkaC$}b%0pSRCFs6$yNP=uvpJ8qw&%*MAy# zDXsA%5gX_L)WmRcpjF#b1=$titLr>=ddj-9w?a>6jWl{EVHNEqbC54phF!AEMHapU z$c3isXzT+W7yh(qZUS_pzFzRt)-!&amt4B+C zOS>(g!u3(f84W`r&w0rv@aLm!%w|&ilBZCU-k-9iZu0kInNnr*<8Wk^xjwmGnw~6Z zlxMOGm6TY7EA!;M2Q62VU^5kbT!XLe#VF!e8edy36rlro4js|z=j}M7F zB~5RrYA$us1FRUwZ%e;}{ZuRu2r5sAkXKUDEp=XIn5Q*e7%w)M)=rFS^w`o%M(a$+ zxU1xmJ3a@XgzCtATe3uS&882fC05=fF^Xq{opY|onky|Xl5 z1`^1esMumnYbAxXr?}cBNi2w_-bCVCknPN7b=`&bt~b$vgB3%xT$va*UnoLcW=fIu zAW}18^73u1D$rcXAa&O&7Xqi<_z!cZ0Vh^i{b=W*85M<=WkK>)Ed6b?B3#IN+^RVt z(J3*p@gPf`-^VgkB;fUcxs}?C)ajADg#}D0nwvir&6f<{_^>=u3sN=(JE-gm*&J%Q zH}+>p5$wTs$y7C}kSOzB^k&fWP&ng`5LqZ)nVk+54wu7$w4yn?x|vR*f}++s{+2|$ zT@`d&t(}fCIpv+(xm0B5-QJcaMYW%5Y~(U4x2sKDvZR=_E-VP;Qc8=2503%gN*T37 zSY-bG&-*ebtrw5t*CXj8OxM&<&AyS8J+ze*yitq--EqnVe zzf=NNqHI^bT{oLzuSy9XcYLLm)Js!;xslK=x9u!D_^_$BEU=+r13FGT4Rvq71zH!a zHr9<=ly?Q;YTAz@y?)Giz+IaBaJdZ1vS!vM42HC~Hc_0r3$-J$COQ}R9c#P5vnjhF z+AD#bFJWgFMJ#Aj{G2x5oVmiTJp8qR+!KdOTpR{%#bkH616QGizq34!lhK}N-848O zOWK=#ojC?7!yRXoL&Ys`wNu&r&BECRICexVZV3L~(GvdUz$H(uCKX#cgd(Th-pQ@r zV8wo)g`HJZ50k!4+9gz+(MyCX$Qaj+RtRAX7i+9&U~RPVB1&J1Xf^6FafuEMS)Uo|Gqd<#?3gamtHnj;TjjmLRjodp~=B#%$Ab zu_El2CIRJHy2(Uk0c3HKZVFq-PwT}n_K2-z6%~|msKsjN*J!8f@#9Qd@?tsFs1Vg9 zYN1cGQ`^%ovC2~QoZO0Z>k=uv+*h0nBQ!0BHb$%;6l+ei&X(42M()=UJ@+y@;fgU> z(T%2;umfLAdsTHe95P>rD((F#qIJL+;JaGSE2}pf`z(?uUuGe?GVXo*$Gi|Heke_F z6ncyzG?7pA*L-;k4piU-O)nKI;g}g1gS_iueCWsk8AL`(O2X1JZ#^EQu~Q5V7@>UQ7sq0Zq|OK%E)|3EHh;sPh@>rR~K`4py|s5`_O3V|pBE{4M9f3euXJ1as2Y1R9PVB}%@dV427>nF z_A(!Zc!CPrQH<|rKSvNgc@QEaV&b_1ni$84}+DONO^IP#Xgvr1+sM6I0*IkcJnQwzrSTb zL7Axv9*sX4`Dy5m?s1*zCsNC!DL1pV^|X%YpI-H3T^*lUV7H|;Hr&>$(l#>|$M&P7ZLhYMIt?v;`V8q;7oSr{6ct8woG(7C zht|P=Nx*?I6?epuh^lwAr(3(-2|Xta1=q`+W&95PJPWBug^^jbkOf6u zmjh3R5D0+M0uKqur>sw?^r;J3hSj*Vm(@#mVCjU9&GunoL?*25r_UvGKM~~EYEAfI4ovv{1jr5gB4x7AhKP`StM~$0+UX7J zXG^wo(*f?s<(`t~e%;9vz%GiMrH;f)(SqEyE0(C%qQUFztpoqdYkLZ-_yb!!%! zF%Ke-oa^C4g0&}q>oXSnii=%eTGJoLUSa_uwYz)NK9PB)yz5;{fmn9o1N25L`3tj213MH!7wP?Rb4-a6A>v(qB>{f_+*t+U`)UK3-*y1im)#^sB?-B;>>+P zHI2}5KQF);L+RW`>J6V}z~~iTCB>2#1JYJoI;Y&zewfJ8+kG4$MjzuIG$i}wq$4Qo z#RY^dJl#Wc<8X(U%5f#Fy-DRKCswNqOO5Z^YbC=lWQv^r;L2e(9Lq~c5h^;W6gJ948@5;X(>How4gS^- zo7};$0*y}8U|>lKm%7StXDq@7_rl!LDQ|VuMCUFZ_88c>w+ z&TGQWD-uL}>4NTgJu%)!0&NNz5?%Q4dv)p(cFO1!AM9W0Sy-2hPC=aEqEm_LQLo`9 z-|59}0(2fukFka?p1EOii$z>>ZjueGP}NV_cUSCP*g6L{Xu7T-Z>#2-Y{)P7-fittz2oIpXBLQ2>k75uF&GVz z@h@a(9N0uXD+AlcCOsB-ecv<`KvtWW)GK#paasL?4n{yl57}O8!~@mt;{nsSv!PHp zSXSpj+WkGb&HJNg-YwoLqyu}#Go3p<+F11n1@xX6gLq3)V@l^_mszW)9LmzO$MU)3 zc!UlC*tf-<;CTjIPLqw62E3&wWFPA~)3D{^*RgBVwwSH>ne6MG$@8pauYrWwf4ypvUaZU8bl6OD#dnPe>&Smq3oZC4j z4D=lpGjsN2vbW^qBPf$X_zz4s4ug)l+Vnhjqzaa={J}(*wjbRvSiKWi?>$d6ZD_*DvR?&AVbs{l`4n&qYB; zI1I1me;jP01v}Y+zzc<}ixq)x-dK_qZBVNhN{}+$GX_3mO>ipxZVV(N&%OVJ1kyMt zrl~?G(O+@Dab#yrBSHT2)ZTmo%hgU(RRM)QS_BS)U5@m-%eh|F;}6pi`K&zBwwX=( z(=Ns#N>=77_Iu;qLiF%0!7=)Ee8$gWMQ$`;UNu7L0reQ?Y>6pD7SOOxL#ysC((3+FHeIrd+dC8r$u@V9xGyqV4M6j z7bY&VMbvNZzf$7xMs4M>PtR7bSlN#GCZBUZDF<&EZhH)(E_ypqYK#4FY z!ZVKo zFry>@2>=Bq^$~Ugk_tu{#FKB}&qgRP01n|WV5aKm@E9t5d9isN`#MA7KM;xv01y!k z-*e;T?Z5>H+XyiDvyE;N?0NeYz>h*3oEU+Iw0V6~gNHSBcXn2i^7p2uViJz7M$drT zQcR42-UN26gTeu9k=iK0;9iy(1RxLKUKg+l*{J(Q3C^BIY)_2NufPL^fu12K%HY9{ zTnTr9L4|kx-v@w0&$NJa)uApBHO~Lt?24&IQeKf|-5kH?l?nL%w1?-}SBavq^oY_5Y+_0=qLeZzeJ*3%mdJT-p?T_R0flbb9lOQeao51OZtN z>RA8tjXXivd0R{76!;t9NoPB&Z-)+43xxE--}64z;Lzpg)V4`|*9z;{%kj;p1a7tu z^3`k@NL&Dfgoki946y|(sUQNjLv7z1X#lm?8Vda3&4Bs*j@0Ml^#!Dj$?;T+i=Nz; zIz_)=M+yOUQ~4Dn0{o%nM*__V#D79aim=oAg$unwok)1cj)n|!vo6F-^nKV{%KZrn z9t`|(^BqVGuQvjK1U3la9(q(}(C~?J&U~AVQIyQb>GaJ7P zj$d8k^Csu!z5`|?{R3n`e!G_T5evC`?9GP%!#0N;N5;Cva3(tOIkx+)LSaQbOmxDE zwD<7&K7G3oAijukAP2wvVNS63;u%7ks@MH9yrbuCX!j;v_Otq@qHI>?o#d9rej0^f z@j?~&GG{Jj`s}91DMNdBF9}r1%yen^{qPkQ3rc(a=d*E0q|cNZ*nSP)D@`{eit~Aa zQ9e^)kuWa_L5{(_>W1V(UfLrqwO%M)B*8OMWFq6=yM%B<-v^YDoXX!bq8ikQRN&Tu%w)$~nP`{v> z)i}DLfqaVA2+%olM4s?;rSU*4%~}&~TSW28ok^dWrA0(jz9z`FR7g!RiTxB^=Q6d0 z+gSMRfcaqF+e3Wlj7ib)6;~?i>9cYsP3qTlH8Oi0b26DDm6fn?-K3nX)z2Iz1okP| zyAC|ASf>aK9F{YUqs5EK4~%>W-mHL9jOI*z2ad)Hx3#yfI(m}#r)9~B=!t8z3hMiz z#t1z_-ofzL&YwaN8u+&WbzJ>ql`kQ@`U+%hw+UoDcO#|OFO!4Kv3yZvdWDSIjcJ8= zAoYX)E=I0~G^AO5|1~` z;aSb~9Im4SQfbiK79=Qc4+=|{aLazhWbvH+m5~cA*yOEu{RC7q41$Vw>gZy2K4mVA{ zZNv`(raBxD5GGxN`4My_E&(}A9q{fLB}Z1jc5g=xb}8ZPhVd#f5al_P@S_&DdpH4< z<4{ZCS29ED{Q`kzVx(pbr`cf--$I^Eci`>V+rjdz2B$3 zgl@n)jD^cZ7_niZ&5NUW zqEf4I{si%H=uoC-CF1Vr(=K<#vuE_YH!mf^tU^A+=+A8%8?K}A{ zz|F45%^HSN;FcjiY@dXhwM-rOXtv#NkME(7KHFluLDbeA4YQU%lpV53Ad2@vvW=;% zo$VV&R2}qTwuX0$+;0O2_SzI<1S_La+1xP%$$gc>7g?XBUPUv>#TJci!n0;kTf~5}@P52n5B4yr!=6Bh!njOQoM7pE`)j8; z2D*$@o7cQZ?e1xjD5vfz_g7@X?Y(3g+rjtI@_lQ~&uOR@jEp8=k)@-RT?|4E2w!uP zwn8P%=u2kQt=Gj|qJo(M9fme0o%Yx1OT4VfyWNMUE0)_rN1=qkp{slG`z>ph3VQ7B zqM2MqygkCjrt&*W`Q3M=9=+so6`3 z0N$d3;Wy02O&28Y$HgES%|6_(m%^xvuXNmM8fl^19a6`(x!G@roE1lVUini91%>;Y zt%B$sPsTVfp!Ce=Yo@f)5oA2~B`96(77TxuvNtnJD@gmfCc{qqMSo~1vuFcAMSKyB z|G=l!4*)@Ol2HSg8UxNL33&07Hs*O{|7`1l zCA=Kw%aL|H8y0&q#@eEWQoc(uE}db;D;weqyJNVX=(fdN5gdXrg9Hb&7Fi|zdbLPw zjV_E(EX*If$ZkDlQWM866m6clFn`tT8SYzAH)$h=RFp98x*Z$WdL)+Ly+>qsqt0Cg zPgT2L7-*Faf_A$Qt9aB%)CU0B^?7Am>V|(lTZUksu~A}$~<$CkU9B^ z+NVF9{Cwy+rC!IiuWfl5oxnUKR+jgNbFg#1MtPB%z1%Z9@=7RF)9kZODiS~fsrfaI zRPtbADng*>>S*nUYiEeE;#GZI2iP5|zIl}An`13U!Wt4wGZ@dbnTGeefUJ?j29s3q zkeEqoRXxYe8s5rBH9Ua@h#@7UrXntCCK$}lOb}!Wz5=g-7^5b;u^VMlYpW~C9JNLw#2hEqK*_^Y z9*CGA@t}}BPmJ^HHDvG?dCj7@W{v4_uY3jRf)zsg-kxFVF}?HJYkj$2^MerFPTM}K@=^KMIHfRk@dzuNoix$w&F2n7wsLOtImDm zQ+4FPu!#I8|xhg9ho+Pdv}x^oeXPmuj1Y2@XVI~k1U#{;zs4VqQz?0BJiR=rwq zNXPV%;A(RH?F8;7QTg%LFH^87kyL}#*%QH^lSCi8P1HOPoy%@m7Nc^*>~uLp{Dt>z z5oc)+nm#6;n&VONalA#Dqbwrui}N#KXZ(ob?p%JWWrYU3ooAL4m6@c??j(h!2ZWyY zujM<(0hS}V=0&8|`tOSNuEhYmr9rdA*~p~@I%6*Xx0cP1>WE{FIex6N6vReHqNq?S z-#~}4ihZSeW@v^60irQx*0A7k*y-b#^7MiGwF?+}DNJ~iWDD)oX4=nM+TZZyQ<5sF59+k z8(p?-+je!?wr$(C&F}QiN&cLDvM=_$T=QaGtYl@rGvgVLx7d{WLNx5=#ZF9dB~m{< zYweD(*&etNs`-9ZQ^@b|vk2sUqk0U;1A;6BA<$hhIP^#kKEQ8}&4i+>;|Ud_V|$gN zyS)w+tEGv#J;}pE$Tz!pvTkQJ3SX*jS?8@MvU2yI;X|TFx-gEP^jHnNz9fST{hUDj zQ8`O;tTG$vYwolsVbyR1YEHJHxl5v{W&L;BJD|gl%ktNCh_M${2?NcR!1(M558OOp z!(3v%2c`{E1+L8L^!mIT2Q0TJMm%X=Zy{4YVyc2jh}64AU+p1Fj^=Q)KPi46ouoQa zBC%RV<~Q5{RlY4VRhd|5BuCQ^qOOIyo^6%Uc5h3{f&FQH=V2rbxCEEHGF&B*K3@&d zp_i)!3Qh2nr4#Q`W(t9Uz|Y(6V>@n?^|# zu8ha+!AZFb#Pf%=Ek{oigl$4F)OVgX5wq{FWBxd@57TqFdDOMPI zsGJ(US&MyzpEG*4{ac(ACYjuQRgb*MseYlTM;w>8jz|`&`84*Fi;qhwSXuRB*IweIA?-G_%blBS*6fAX zs|nD28j{glHwX0hD)K#?YbalT;B8!@qAImqGs&@>RL-yWWlp7M5Nv^?(GZ}3wdTv~ z_oz+X-+SAei&_;laT^#8cB5jlATMHT#f|)8a$Z(wE|&$hwm|HqNcUl4a*w)Mn5}b1 zaXZ-hfcj*WuTSv!g!Y{Of}?nf??%LLy|eAHPzmMEvs?YP82pXsWial=I}?(0zo5gh ziZ)+SCz*apBh80UT~Ci^Cu6)WQfGuV4NXW-mi@6V^fM`B9iMVjx7+wkVGp6zpSG-6 zpli8Qo~xF+%=?4dD`^vSNv2ncnVDj_wW?I8y|L=+Y;0jvq^+2htRu|y@Pu;R6pb}MX-J7OFC8;k<+IZ=9l zIp(nxUCg%|6~8ZykD6>_K6I0b6?(jkoB{iY^deqzw5qadb4NpF%$a6Z&ib}g8X}|+ zYdM>9)YJEp-0YIOIrl;uLz_S$(_R7gDWVrC?}(7PH)n_Yec$~&Rn44!Gu`4>YC2@3 zPqq5s{Z@c#EmfDtT@VehYfxr{a)sJlFz&=;c6dzatvcx`Vk(M$ql@^aS2j_-%N#Xf zSR>L1*r;5i-l*gn&-~yYr9*>{z|B@Q-{;3FB5xOhYhiVEi;LexiSlcp8|hunwk1a~ z0-2@@At&(<;#P=7`eZq@3ampgWwb}SJR%~sykzFPtQB|}Rd4=RsePM=mY6|$^VKTq zSpXRnZcJ4n5a4>jR)+M4XGPB_?0Krw>P<_I!Pen!qakY-<6#y^sDTSNnJHH^m9fNa zlOp)~D&36&rn`*zdeX=Z*~6|TCj|{DQ*jXu>WhHl%GD@Z@0_GlulTrp1Lp}D zadM4}P}}cswjf?oO_>A&(0jLO8_k4q3~yrG%*s_0<%TWHeWI-ao1MI)$+4dNu5cOZdT(!+i zFaAL(vyr!7n6ur~Seua#=Kp+ZZl_&*_+)h!h=l&{GBiSPj%pwohUzmofAyWM6l_li zDZ6*P&OPnV;dBnTiHWQWo%D8isWNX;-5>A1neVat5o<@ngJWUD znHD-BDvdQFJByI>o#)h@P1Lh#(izY!y(?XD$wOScL&!A5*ttdO2R6$ZR#J=}taKV( zQS_6>S<0P-vz5L+Llcal*$|T6#Mi)|rnAiDCq{iPkaJOE&9X|eo_FppRGp@)i)PWL zp`vm=nXP>CiY;T9Vs0rVk}(HGPx}4P!I z@tJB24(kRO?y%df=8&&(*$?I3hic@EUvx^rP4ugqH-t5UIqisK^^0)OBm(fyaEAx92 zK6XHy2-yC#v=6=%Go;;jJs0;y6nfR%^{!4{9L)(RdCL**-uDqE(rMkukkN(BX_@iN z>n4yG*6`8IV6j;HHs70hng^3(mziJwu1=0y7F$rviCbzlMf2#S$9vSZHR8fXP0bzF zvg`{Af0NNPu%!ajM;(ruu;}ShxYYCfS!D^C%A8|AYMxL+?!Z1O?&ky%;zE~|7VJKU zqQsM9(vCKmD*+04zq88Qs&QeLzdn_Za*={O>Oi2cO&)u-mkV=%Bv?7z$G@ygxb{Cq zL$QlE-uCWH`AY%fNz)nFHubxy!-}EZX+pL)H~l+a+Lv7vxV~BLS!Vxv@%;sVVo>(j z{+SLVda4p44emp5R^T`D^hI0qck;|p`LcnC4RjIX7o?!w>5iT=Env`Pv$=xD zWRFQZ6Eeu5++Znxe8(g;?nSf*YitL;@T`$Phh5IYV6U$_3`5l<-D@?*=A?>!!>Rdc zo+IKV5jHy zS1*_w;&Y<*zn5s(f7wCHQO!%SSY^bD=vtF*c~zMUw^H)X8=uyaWr#9HjV;xu=BU7( zaF~ASF{)YgjaP}zO0rkYV#w+7mc?Q%5ZqSQAk2CC(^SU{Y?QgUekc;*FzQ7xbWU!e zrp(r$|2^R{4LP3m;I}MBFJ(HQF;8wx;Ct!tzIfgwSDW2&xxp+D1ld-Xb>o5hj z`@~{doP)VJPU77mBbw3lSug3Wz~cXC-gijS`XeN8 zW#rWkKUP2vlxsXQZ^XL*3B{4OU?AWuU)MTz%tZ^=ed1_D)*6{I?3ZRF`4^hbZ+v=6 zFG|C9c1+yVjY6d17?m{FpAPU#agw{YdnEwUnlU6XV@F~-v7v9GqHRV-2IdOolJUWV z6GsQfeH*v0Y*JL#M=!&<%AajDEc+O`I{&)x94JkdP# zeZ?)ei`=qy`AKm)e5!FBDYRYlN2DEj-z|*u|fa&f|;lF6O&d& z)kfU6%l5dhplDLONTXE}nLlgLE0Aj8i1=m6&k)GSX8!Zq{P#IcI2x7UBGnLgPMusf zw2^y9d*fI40ikj>3@V=LmDiu$9h7?kfFARUwZDnyK&+g`3_cZi{g&!Pt{!^NFk7+4 zLz$C=SM%!KsLKrWIdh$022DNjwN!;-E`_2q7gXp|(>`xI%2-9e%1Mb2zEfI@C{$r( zWSJ2~4OUcW*V{eYi}|W@w4BKkv!2@E+}02sU2It3xcv(X8<`Tq>}o8>?^5W2^Xk~d zbe^s`J0=2!9#uaxbp=iW+>Kf8E&Ix=h|jwr*6SoAu1vs2Uk`&>L98SeZ?wEd6^2uN zcFn=OrxaiCb8`%1Ms(601u;#w_-A&S@EI?$MGtj^?pW=yxz|~YMW+90|N9%#Wbz{- zw5rYlbFW)hYX&0%KCI^&frpRkEE|t1Nmvu~S~R|~_*G4>`QMo?B8}+%b`Gkz$GmF^ z%HbL77*5#b0ok#|Gm8(Q;^A*g?Pp56_z^m3m)sTU-SVGRPH{m(p?murtE;ZnB5*Bj{aDF9=v&2r#3;qN^jq(^C8u?qy|dyZyZ_ayJBs_ z97JuXYvsF}pV?anQ>e|fmPMv5`H^P@!11wo27V@Zk?sCsn&f8Ho^%#Vw2G zqW+pPG&bXXu{Y^H*jp3tk!+dZ$J!ZK4)42rJGnzB=&sygCgEJQ-a4$#6V7hecGKJ4 zOMKcE0tdQcF{V*PP9*P|CZVGq^&IW?w5)ED6W|a}2+n$;75m(rI=qs;2uPY9VbJat z_AynqVMdmbzUOT`5`Ec8fOL0Zaayh=_x|PT1U}v_Asi~jc7#u8S|>|Z;>j!#M5<&= zZA)fm<6M)>RAYyd3>8L%4%f>N6IT|>E>HEHflQ;Js88%<=rEy zgM&V5@lcIp4OB8M90UK--!yM*3CrX>yRUeMEV*q$!16Pw+;A#HM*8hvOPZKw*Ck&O1ybd_ z1{L#4*SBJCSNZ&dqB>)8yG4?XkAA2lA5@;@*^|7Fzs-!eh}p@5kF z+4`9NxrzU;RO7!fK`bo)pGKnvTp`;Eg-*u)m9U>o!rtxQGV>QSwRc-JKxN?og9dYR zL)i-Q5}HHWq95n%^l}CCUhHI6WZYVKb$=;Ym`6z&58cY_4t zCil+~_s>!HkAd&&9~lAA3x`Jm2~2E(nt&^q0#gX|38<@JONJ-4!j6rsT)(IL@q(Pu zoC9BdeRawBZ2=#|3Sh(+b7JOO-H7V<=FrJ}>r=+Q7O%vtght$0vwZ*CqnsdWEvA$4^1_`zEgO}{XYn+BFODU^dVD6r1cCNPC#!h>JYTSw+`4GfeF0#kKnTl>njk*md;kdPY*!li(TlC8Kg!4 z%{CCa01gu7Gyi8Eqtzk&n=&>!b> zJJ*Ny`tkud`^`e|?)4g%3*<_|g3W!09g10RS*OnGUjb%i0EZ6%@w;8cA3I#YZm`J~ z9_~-s`Og`E-_l7uKInB9Vm8~w&FiF>>Bs}74`5XR`(jDYWS8FT9eYUA`FxG%^zRd34W~YPRRd;dY^?u|yYXnCxz1w`yJRK- zl=;sFJ?@H219)h=gqnRAid>w9}&N5Ycx7K+jwq6 z_`7^;*L&~sNWs87foT;nPKiROWdAS z?u1o!>O}T_ZbfxB(8{_IwTRsBdCe)sp{-{Y?zo=1*=7D^Y~Bq0a7i?gKOjOt}~^lGqZOh&!s?1#8mu7Jmie>foJ2`*_nE;QZsjG zb467~#X(Bw*WHVi>%LD}lU60vxug9?irSuH8c@8;kGJv0jQLRAXU!S6RmiK|ZZkqm zT-rYto5Gx=wr^tKW4VeE!qz8LW-BEJ-vs%R!S`w+4}>>$~c7 zBMzfXngK=_MHsEvGSi%z-b$~#aHn_<<_zaJf%=`X)y>k2{_OnIL>Z4C?s|S`6+bsR zKf0x_o`vi~-l-BF7E@Q1+P@jmoVol+D?3E9g7&WNg~MpuMOb1SKIgL46`lI9vK=hv zP~L!hMYcRMklY$z4Y~Bda?`BVykokN(i_vw?AL-zw@(BixDaA@3|iS{x70l55-j#M z5ASPvn`N`z{ta8R*DVcEOS^gg;!-mP!Q?TkLLN;&F2t$i{mB2!=>ql2!xUD+$2*qP zxD~c5Or~DcWEGS0=L0+AX7x2p%Z2+;NIs+K;)H@GG=6$TqsLs6B=K(RU`}&8al-0u zFdTY5ZFU!fk0~U<)oP?z2Yi|NWFtL}-U3&-1nS#48GfP!@psO8)u5;9ycHEfP%!(R zDk(fMvr$3|=NGH4-xu$tbW`S~n;?hyKM?TcHE2{?Zy^&JYwpn&0AiUX!gz`P>rQ>D ziuMsv#2=mPd*>B5{=xt=(={pA!SbCJkh#xuEnoEpUU$8^Yu%INR)*IT&?Yy;1_=g; zM1G-UE-4Gv&T-<9X2KTnqL7n(h)KZf`9N_BBE6~~qj|szA|P-(!)F($!lGP3;U09K z(%4_-njhPY^)y7ITk2Y@&CSn)J#xe(#mK+~qvB0C!B|jRAy24h1g{ZUcT%z%b6-Q9 z>e(T?UDCcU*o^(FfhL$6(U86nfO7_d=e1tuTMO19tEQ(n_Le^3b>j1GiTB&})rN$k z?jcuy9qs$`HusK@ib+y5vO(u~S=Yx(gROeGddJtaW@eUgRLTDB()OmAzrG(Z;F z^De1l`D?ij2tS)$%*`zI`ra`Upp$khMIth(o-S)Y8w4? zwrSyjO8tg&f->$pZh?Z-UH5&9q_-bhLAX!9_B9v({$rtcxW&L+MQ7aXxYgfUyrFb$ zPLTEhJffno2-CkN9JmBv%QwZD9F20rUt325$a=C#avfNQo3G|k$47TsPFz@&(s(4s zauUjzeCuHbDXR=P(cJhF6ZKIEV`Y)~1vwV;*sCmf@{Pr@G_hj8UB;(K}j^gbre!8Mx7ueRFR3N{SifXAcG>V=V*@`v zJKKj z5vIo1I&<~O@mhxRwNMYhkvY{aQ1vzn{a$(pA%+23&CT0+)`~ZFuM%jRo~xeKe?=jQ zTAOn2r}iV4ZqEybwqI$mTj)jZq20#eU2fQj$K_@5g8Qu*DT*xzwk<(3e&j@QaL-s^ zf9woF2N!_)ix#?2QBqkG;RGdf@y%B>5rqA9)KUb8fMaLK07tWZq6}KHW3M%e*-iR+ zpJwXaQ3z*f%y>v+-rGhA#wrQ|UH=l~k6AaA>TVO>U`VhZ{v5#;`c5BKmp;<&=$)7) z893c#`WQ!z2rLGEm?GHjjvmQKipfS?gHG<&wUkf3F*T{yG0Gw;Lgqo!*YZo#ggUoU zZU-{!b>x^bO^Fjn>C&%R>lGz)|e}h+1X0P~Keoox?p9IsF7Zictsw ztTvs~miE&~2rHpkqbaGx?rH=7`PNi76l8d?1rf!fp-a}9HnD}`Bx+IAQx zSLUPjA3gpI!gWDix0S4YU0P$PysCWt8XL*4?2NCZz%A%=MA3UXEuCP-LWb%A@7E|f5S z8#yWYLirog`XLl2G;Rn{*tSn&Tx*&kHQZg;ZuL*OznPt~QsPLSlUpb|MJE>2ANMu> z2ow#*NKE8zm3$}@&4|t+MB+$8?Q5yG<%m{}sB8vn>TQTmIQSVCioj$a)nV2a+RAQ- zBHV7Fe&xa18GZIk<96C!yFv-}E=jYT#>HO9Ta3t~S^hTrRP!7Eq;??}vBGv$+u5Kp zt+_2ucATetPQnv@r8Zu?bJUcgqJZ{Tcf?z`awaR(DzyrDaFfx~_f&BQ{Y-UP==L?J zW)nsoJPiudRa33Aydr$LJ5Y?NhQ~r%1e%{k6=KJ>{t2z@(qw-B8=#scM*E!Gm-ypm zmYc1t<&m|Kh1=kM#~eU1_^?Z42r~jlFFc4~A}%sdOCP_E|dkSbMi=n|fbadU(Qfdq*&K$4XZFMDBi`6W`>y zIt?>1^2OoM#Cy|g!1@qwVafDc|ie7$k0tP4^ua8@My!XMBdqgum6%5GdTJ z8KaF`{>zy8&yWcIlJ*b+83{ocRt-CvV+a<4UbF%&8s`n_XR6{s4Fw8qI=r z;^_q$r|AAi180HOv|`jBrJi2~m^&>TI zLhU71^Z9h6qcVA>w=wHWp6{zRJr7FWc@`a2s1o&i;PpT}O7P6ggdA;u&3`e zf*QBh>eUNM(wrW1v~h1m#0Z4^==L9${+M0sBo7?C#fH{}=r{er=`AOb3%LjeSBaK) zyVR~msvHx{3RK`>Sl|^oBcp1*w|H>Ck}Tlu><$IhCGoCTikRv&uyI`<(IIVGOpn-S z%1D9yHUC{O+mu>pQeqzy>V%KUo|>x_Xw2to?5P+-hy$Ss5_ve6ChN7grZz;OVD&lc z{3&(q$rw~(0P{wqgM`+ZQpEaxW|N|GhC?z^lrKyJUZgd>L@RfYVS2W$xxHTihW+m4Zp6tgd zu>2=u!)>z${p5;60cnDQ^qYK2O!%q&*ugXLx06K~Ha)BmGic~LHwy7@*3INjD=qq- z$1qyM8zMrAvHjA0M0x1$MAhY!hQ1s`A!@@!Yg(vsvP~&3J^3C5&Gort#gzMv2iiLSsg@eq_ToZ6Tis!Tkxf*%MpjQ| zS<@H~BK&n#hrZe8vJTchMlL6IO|`paykLoQnjR|*;T76q-pQ5-O#ec$7lNxp;lw7~ z>K^)BArzDwa}5P3{`fNFvgn%zq$Iyt%Cei<-S$^wM=FnhhBt&-Sw}Pu5f|QcVv@!|&%%$EI>Q!;qa`c_*8V-F^W&D?ts3!J9yCxJ;`e;D9mGMF@{5_mBzI$e8#4|C3K&*jfS^#OWKBP46 zC0}(t_f~>q&0btV@1jsYG!$RArHm$edF#0^j)096nLigfuaO7?Yk7u;Fw!?U&>X`^ z&pDD-LWlzUWvzc2X;ONSXdP#vmz(0Wn2Hh&m;!rRQ8qEVFmbH$Uo^X_9FNaU~=BE2{&y)AWqYe>IlxZejEu-v`R=rAgd);;6{`#LX;!fVLYDG zhRU3s(?dcXUVd;16vs8bH`dO=G!!#&E`Y#atIhG{C1)Iuqu769$a2pQEL=tJ zclbK@-vH^*7<;tuBHv>_USqh&j*1SDqLvTL_fu-=-GL4f35 zT=oIhXz}5Mn1=F9UB;QgcvXdi%e|j>z0Cz(SRTTMs*!To>}JWjY=&vJnq<&^#;DP*c?n1eg8837qsC} z=HqC8wW#qxScpUbJye7D-liv|+1U#4LAN83-h0(YK_K{x`w2N}byWt$6Cd}beo`N+ z&qY)sg4T;MDV0B?jG%HVs7hB?>boPECk?sR$D~^WQtcPFQ2UI!3{*~odNi5qUC(zu+dynte8l5JeqA5Ui1R%Khh>pUwIGcaV*|@|l?nRyS~_?jqDFJAL=L;chlL5S17fMS!9)aXALbV0;Z0;# zJeSL!VsI=cOADQ2z0*mVS_1zj7iAH^4_>FB(d(ulf74B_Gre>n7r2h4+~a8(1lm4V zg}6S!|;f+ zZd=j2TD^523Ss#GWz=L_e8)+4*Zqu*w)iBfjV$N~DMkAr9$nBE zTN+C&(>}rRp$-wxR-E-D>LC#|jN?C(bdhrIH3!F|Xs=&5=bEpu@01UunyS!bm(LD{xlFwd?rD}zM71Dqa1GgzYv4a$ z)!whzJ(+#PZ&| zr`ba0h96DRRN7?E>!qB;?2qnI&MU^58=9!#4k$tv{9NZvzVLiNTbzQ;oo>Q4jc~mR z?c{6DddJ6D+~~gPj_dXz-|iQaveeR$zl z8NoB}&Dcd{tyDC^d7|@+MwqD~*}sz5+s9b`WYv&Gz>wB{tV0jLx}APsXk@v={zt_d zQuG}UeG!VNp3b=>D-lM_1?)XB_O~_;#zO~=vvzWZn!Rt zgRO=Y(anxOmGJ`guG7_|YV^5}P4G>G$MmmZZMHLv{#x%=F5umcL}Xd}7TuGZTl%Ki zxC`_TdIlWA9YnCV?zQ1uVJ=)!u@iUW7$I@=$ojUO_MLO{CQk z;E6?fv;`MGN|e0m5IKk%g-%tCUKjXFtV_smPb6!VQ`u{N`^-7}9~Su6m`! z#kId_?P<*gOmgKKv1j!)aYqR&hRz_w_RJxPnHIVp)pqr0Ve9$RF+3NEf@{vE81AtH z^%+Gz(#JVCM6f1<;S0l;In>R}eSb>MrlB+?|G}Y2@71DsvJco;Szn{MDXgT_C)BPN zd~^{~fq8gTZod1r&a>1m>1JJ8dtG z#G?#UWhVV;VK!&)(0i!nkPwn%et;C*`U-Oxoyp1+@+E>`mH-c1ypLxShLbYoJzxHg zfB$N!iEblE2qs}Yf#+tsaHvG8iM98kBK8hiSox7WbX&cyY2qsGU)b#KaZP1+@)OK(vosG=Y020$$xsR4xz>_q9E8~f!X$1lyqmAzXm@s5_+pVbcNbROx=wh zdJZ2!y-87Ub$UA{p>JSeWh{Em^Wl1QYqASk`4iTj#3Do-2B!8H9J!#OgOwWW| zi+@AGvf@}z@>`*j1$mAsjxHu*wVwi;%M8X?0j`aK!yjG@ovd5ZxoX5z_T_hysokIE zc8ZdecDQBp_6<`~Q5oLI(j)=(c4B=`sREG~lspTCdw*9xS0 zGOyjobNPWROC4@}>!MiAHT0mtYLkzDyGo7^mfH9>MX z+!%bu#OYx^2Ac+V>?Ee~l^oe(xt=4ZJ)_jMAyc-;V%RvB23qOs`QWVH?)8AmtYn>B zdMp=PO+Q668`|~KJoGcHNUjs`q*y6&En?g@i}4aSpj9AyCo7%ZSC!NG2awAlp*%*+ z-N}jQPoOz$jOvado>5Px2|e8mSDT~S{5&Mdc@W09_xBSFxEhg~%RreukvjZkNy?63 z1d|6}J(cy20AJDQfC2t(xdsTcwN*ty?2 z4j=Z}uB?gBwZnj(v4l z2zkr>12ePe+$19DFE@cWSUw@>^T{wZrx?{3+u%0Bv?8A8HZe>SPj9#wC#;q%^F<#T_;lr zN{|JCO}uXLKdb%bX!p3E2D+nTn!{8g3#PRfoRp-iKyZHr@r{?uV2VACCVL>^L_U4h zWenDjS6)+9UQm0mBVKoL=6T#vs84!2R-`)~`5isj$$Co*Nn&-sIqkxsI#KKCz{pbU$uDJlGKGfj&lG$aG95>d8PV+#$|D z)K=B{*F=1~fDnn8ee!_E;q3~X#$HB z8BG7^)P0i!89PrCP;zbrKc<*lZWGE7`W>J@Hqipn)2OTr`s* zh1mYz+(I*LxKQ9j#iM$-p~_N@>50ccS9u8Dp!5f}&)>}%qVkN#kt!U&(DCM1cR;Gc zR2V3R9u4-W^Egn?)q8C;f=Yx>HW_x3M|Ap)hlML{MhTgwm)l@p)>uOb2(?7&W7Sv? zDYysvNW>1RHMO6`0rvI7ZIEI^z5$l?Dz4^?;4K>SxEQEN3GHE+s$c4#qi`EWhPLcr z*8;o&KZnzfDI8t)s>Ar)#ep+Y-tK81=pfh;1!)OwSocWdzQXh;cBT)w9l z@hUaElD^67C#)N2pW=hh^xb%if?I(){r3=Z)#pTrb7xzBF(XcF*e7Ljo8^|ZVJk|0`(1!sO{uS;8mJMJ2zjvHX@kcThHPzTDdke33!fK~FfJB1%xGMlUq! z$HJM);-lsg_@OH6@rH&yXhCvriBL)_b>zbI-hZsLi50w}fBd8m5bcF>-J18RjU`L` zHcwZ1Hhn3XAo8Kdc>C>Gz$sB>ShGnMbOoVaIE~nHonBF0ou4~#Ut<*o9U>{x;B9qp zL*oPL3UTc8h@2C+`g#!2T(9|?mh{i)aL?g`Qu+m?fbp9DCShQ%#8+lQPeBOzb6E{C zPJj1Xg||F;)qu?GR)?InV@AjuNhj20kvvlL&md#l6fOSMlfd&5=toyu8AW4Cin%IF zkxH@hMOn9vFLS$YfO&f_5_(aIFu7eo*1sRjsU$#17FG0y%S?t}Z<(geaT++Gq3rsw ztIeo0`>}%PRQn-^$>IpUT`cuqHDFEm9;1$LmxqO<5`FsrT(q zuZC)baPU?Jjuio_S|`(4`Au_wV})a>pa64zx zAH$y(8{(p}DMY#Y79vl^QWGNRe_swIJLc{yLHk_;r*J8{qO|;T)!-w9VKoBw06-it z23`LHRP|rYrT;6aiiv^gKNUnwgp90A?Ehh`{$HxqLEoej_7k;%A>RC3HT^-n4X^EHw_g94s_u)58#@_o<0{tEf1hhX zz5eYy z(M<_;cJSUSrSPcT(Z+Gd#Ms{1$&9_p#k|3-3AHc>x+O@L3iKI+5S){d z-d#;QH#3a2kI3&3k2?3{v&x(C!=+}$?d8UO+nYBn=xTc6_dC6vi=lio09QAF=>QPn z&QA1Y+z8YG#F3tn(eADREFcavH@K8|F7Lo954oo=m&$+Q_S3V2@PYvJ=mssIAJ2LB z4cfoCz6K9v@8Agj;R)Eh??ncIh3$hgxd34R*7CnX`YHdhg~$ZN?8@&z9|6z(@wMYY z2YSp~^~-zO^_ra8nHhP^yX!?rlN6Rw7FJBYq3;K{L_}_Q0d--mxdXvf;Z6aeo3hCP zt$qgG0%{({F`o#~rvOJ2YZ;rM?muLoJ<i0KPhSKGxXs3&8V_PV}ysz|hRVNpBXEV=9;j&@^9wjtnipHl_Fa!Vh8! z!UXcmH!FL@MqZubvmL;1&6 z0jCfB2=V}tMF5Cv-0}weklAtkC7%g~5Db()A-ikye-J(O1rK|}PrD=U`NMJgOdkF{ zn0@LE|L#8dR5kjPf6Ci7V*11|0cHROfNKKFoB;aVO5b}4KM9~dAbTI#Ti@xA-jb|t zFP>^GZ-LPPfw%9e0DCWW^Ye3qcVF=z)O*`cb)OTrb+vz69n}Ev-H^>M*dFTEZ;WTR z96-gFc;t8Q9=Cd!Us=~ESJ&>bE1Q5*nqL(Sp#Fz962RJ<^D|EAY>tbeDQa@o7rN!9At@1}YK5Lj_5!Tt+p1Oa1PWwvW~^hZUVzv6?N-FfmCR3rjDJCLAbs2Jtnl@YrK5= znVrcRMfQ)_Ug%%LDOhB!eCkkuI39fIZruDH7Gk^Dc)>XuhAkL9P7x|s0kYw{~K=P^>A zbSak6QqeO=q$#D7EYqp|xPcC4_@4PZJ+FeP-L2_dBl(Vm3F;Y=x4iKhOqUCrrZK^3 z*UH4QMh^Eq#htT#1fku$cxhReC}Pqd2lTEeShY_K-pn^xi3a|;(kiBWCj5pH^+1)v zD{Rk-ZLzcsO;@Kxpnd}A4@TEswKNt3Y_0@KL)8{cF~c^MMorKNgw1KuRjpf=j;U%T zs5Flft6d-`oxl2({3fDpan%<0uEh1nrl*q~`q9UEq~1vhgDo4LOrwk5BOVF;{C}EU zQE{-AS#%D|VksLm=9k)K=ev|WU$mFWQ%D{$udpoSw8Na92$9&*>=XHc-`^Q<)eeC#}n zn(ld$6`KhU?y#+kH8GHlNO*`LkD32Ko4E)I!9tQ(A}j8b%qh@cxs4&5I9xf1=2elq z{2C48xUC@tJZyZ{T1XNEzP86w=v}_l^iV=m^Q4?WpBKmVDWHxSiwW4I4VCnJD4GgS z?@v-r@cFS`&`##P-qCB# z$s%by^ehie(V?N({ z3@$6x`{5KrIse=c5D%PPy0iQ$4a~4#8cqHbJSfx646azU4m`gXSje<^1SikQZ^-u0 zG%vaeDO|LtqTTbyb=BQiS%(6#l;AI(mHk7Zgi%iQeT~VOp?RC*!DxM+!gW%qmMlT{ zTlKOvmr?K?Q_GWN-ii{28W>LIiklu}xH0-=5N#mpqp4687#Or>#W(67YY*QfY~FK) zZyOaHL>Xje0}Bvnil6+7!?$&r~M3Rk@ft_}^KRqJu9eJ$p7k4c8KHd@n!= z_&HHApgQp51mzsObnyr`ce}T5uC+#NEAVL%3`UiBoR{azF(yP3)EyM~K9@7i-W8Aq z7_5g|-Hbeo5dZ3ZbD{^fssjVS0xTOsF^slA#L4-zD()Ig`ox>9Pb~}THM>$@fhhN~ zWwkSA%heA7-OPap=nFMdn;(f;MhA72^&)Pe{=iw-j!~YJRT%4{Prf zq*>IqX;!6e+qP}nwr#v=+m&{uS!vt0ZNF)|ruy%miSC#`V!nep+-o0Sao>BbwXetb zj$9)Rd5eN#1h1FnKA_w|#8T?0qLlRQV-UV|bC9Jn0~GHT1k%1M7D#4GY~1 zF3jL&7r=V(23KxfR`}qKp-f0xR}D2w4I-;UIRZl)MM6C>4-ek>Xn3|^zn4N6ou&X zxVq9dgmuRp!}bdakjlr$sEq9f%cK7Z>v|4`$8(t#R(zw6h>4cp;EYupu2srikqThv z_R+CL+fibypL%jxdHAjMLep$9&P)a0g`CfiyTLu<)Xm=*Tb*+b7z_2cv_bFux5Y9? zOAj=2?A0f&+a#GiIR)K;X*EV|Qmap04vokt*70)8qtK>}!8N8(pU{NIGd5Jd7Mm_C zyqOkd;GW| z4jnA1TBPxzJ`O2AyQp3!=ZEn$1wv#remk!Xb)#VB1|vs3F|`mKV{ak%)4jDG#JU}v zvW7+$08OX}FG$DGH2UR1R5mgKe*`DICZ$9qwMYMy;u?F<3q@+&#Rr=g_*`%sI5P^e z#|05pdrUJtD5*lZ^rCJn4Y|aYRp_xlQcu8d4=LfU|70I9Y&vP^I)hX;8V)YbQSa|N z$<9iVY^V$mthku?od7HD6XkFu|93H8r^vtIm?*-mDA9lYPfZbJMrewIhk<18ZTNev z+$00slDsx{idHed(;q6L>-8ZEvV=nz)ba4%Ikx+*Ef-ubCF_o{No1~K2&lC@-m=1L z3A~aO3$uat<@34QsOZ8&luVdMbH=bge`9Z(oR>nIw2#*}LhD(kpQXeb+Xm~UN{g=( zPgu=#vuSl76#fpWaVy&m$L5b3ff)RyT$!}tyX2YSdC9qXe7nO{Tle$NHuW#6axr^$ zd;Eo(occMWZp#)Twfv4qyuWwHHhQ;N2^rTSa6x*g%XH7;Fe?x5>+kVzPpFU}bJws9 z_y;I);619A=ivA1Fw$*wR=gk8AnTrxXH~tj3a~=Wg-xQ0uGqk)UZ|} z;BF|v{I&oyP#Utjb;J1MIFEJL;$yikU@PAMm|}CuCi#Q5&phDgT}rC0_C|Vh$-ZJ; zKvu;pYj{I-Fqa*if}x?%8v_a%=9S_Z!L_r7y>Mo_kfe1YWq=*B)s?G`gKi$DPg9JbEp z>(9Qv-$&T?eQ81If3U2K80Y80?$ruoZR#%j-6t{DD2ius=vdaXW?*eua&ENxTT`A) zP~WS{2JHjINcreoIIl};06@@{)sT8v1lg%f>~cI9`=#S#*5&CR72uIXfsGf*ggsmm z!r-b%?RJAUO(OY{5c-767{(Qu8fVj+J>RGTrY~N2v2G0=d96e zU`t6ZsPSPS_t))$6Q*lP2oH&7rBd_%Gj3A%`!$DzRf835OQ&!6=CKB0Jg+6licc>q z(j#dgXZ#M4_zEV>Qk+2F&I`xS0l09}eT5HbE$m1T{DdrbCRkO63ddl_@b+VYXFxtB zJ72C>-p6a{PFWWk@F6^DR1l$}2;g8(O#h%(o4dwtD!OrU2|Bp?Hk}7rT+sqB3Syy@ zF1|zhMz!dfq0Xp}oUaegP(Q5v3fe9IE?Dj5`N+^T)BpMHa1(+yYplQQl}=p*oeuV> z0u_3b@JyId*;`J2e>!6JMKS!9q%J4Iw-+aO`5CZa5UxqSJisYckc(8Z7PGKqW*ScF zYMkV+49}BCj~B4b)F6oxeC$;nN!9QukQiHkf-EkYXj#!F__lAY_$QV&Rj5CwL#br; zIph;7*g(1^adXrWm_zq&a?oY%@LRHCWGA?zb@eZrEVpQA?(4v-ig z3$6N`WOTJp&cg=((@q0riyJG6x6&(Cd3j^+AoSGwe$qQ~-c@Q-8Gc&ezHfHfX&)zG z?%~v%6mu^%vTYB6^h^1Rf@^P$4FBjtuYT`uQe3Ui9-YAcq*U5OPa$lxeiso4j5amP z0ux9N%7ktsa)*>m3V&9__*~dfMD}@;8@bK;TJuOYPCBtxMe*KGSyNS1h`A@|HlJLY zS+Q<^oMt31QQSx9H?6m0P^{H88LIHt9CChsF9-pE%b~{G+(1QI-vp!HzSUywJQ+Ii zVWi=D7#_H1k(A;~+k#+pg&fiHZ8#4SP}z`I+FET=2>x%A87?eMrI@ia3!Kitw4V@E zHZTLa2U{)PiNo1e*ohb_|HAsJ1nH3vlgoJRnLCmW^M*(}6@%W#o`Bo|%h=>%M}HGG zv?Zes(h*eK#^r?XS08Pt&tsfjS7b`NH9GguSq=qR-iV zwXqGATN0or`VM-3U@#otV3q4Crww>hAaFcTbVgg7Wosv_lBI^Y z9ozN9j!>C9qe;T=Vr+Iu5(5~sgmH^^hLK(S4c+5~vN?M}K+Yym;pamWhH!G*wDF5n zdI1Y7cV_GrP8f=;DG2h)59Bcl?Q+h5(r0X?pJF9F)Insw!3M=(3Rfo_qtXm$V~dY+ z)o3_6wHlcZ?6EE*La8*#$GtQAT}rol!YkS*;pYVKVLHCSWiUWP$%o14p0D-olHCm1 z1@h)}$uN`c1(baE zxqqb9Wc>R;&U6_`JgyLhcc}_ahFn+_W@)(7tlguyDA^g2WJZ({^cu#$3q|OFI3NPJ+F;`a4vQ$Mgyo`=5bl zI}+u|!_%YUI;_s@;_lC%>WyKUEnN>NR{v=ZDy7_zpKes6taA%@(CeTP1>^V?zD+L6 zuP65sNF&zVkMKoq?HNN{Uzqk>ETu3Mx$DN1-99QaeJv76_6qtrhQQ{rB_Q4OdPu@l zjip3TfGAE76T-mDD<|?q2Ac&hEs>rUe*j%JSCD`VHH&b{kEE?*yNYppJs~! z8Cd|upMMix7T}Ac>4ZaQ+FF*F)o6AmSCuGcdD4!7^rN)+AeN%;M|vrXFiISZ*aTq# z1j<76C$-;SS8q_qszvK&wZ{ULc2vf?MtDD(B7#YI+vuw88D)_)Vxjsrb%V$ASZ=ft zQ0{V^mVYEE>JcKl^wz7YM?Y|6P%8&{%G}d7V)2A(zbrpL#DqVo+DFq}%g*^AD|ki-Etg0Ro8;;EglsxdvY9+Auu^@j{)UjO1&$^|Yq)7|{sYfB!M}^M9 z?v&}szUguV`a@Idz_d5?bPdcVZibo9j0hs$?84^x=+l<3SC;YwDhEvBiWaOR`I_!# zPN~*fer1~Cdzd+H7(9;@X!5+vRM+(HEaTqALh=87LXBa3=Hr7(m$?dYU-ev&wZ%6A zp4H(~{d&85VE2ry|5GG*UnsAGYK;a1wAenj1u-^E^5F5tkuZv3t#*`26@zQ(0+cL; z($L4%k$8eZ#%cY9@#CraxEh>2XY&YZ(N7le`oi6yp6G3NnU3c1NjKo0!U;NR^S+|><^UQBc5e;QhL`6dnx zlH!~ACBC%o%#S^q%?PeW#C&RMQp1K^R=n47h=OEr=6~4FCS0JC_+Srm;gD4CShnkvMF1Q!&0q1rdpxxp68tJ zpc=Pzrk&Qpkl4~DGHz`bgqajpP^vzGl`5w)S&W|cq?`YX3}4VF;!HIM^dt}`jsvUN z`QOzVJP>9rVfUDs^op(d49fl6+hz~)ovAGSGMkV!KZ7t4f>V{^)x=9`$$cZ8JI3DT zUhKm6+1rru45(=RpYF4!*`bs%kJO-1Fpz?%iIdLaNoF$ye+BT=>Sf02EYPJfw~9#M zSjx3|hg9#fP?#iRxMWJb>grImKi=m_r^FtUu>+13g8JR)zTl{36l*rO@~%h<>8wTA z=>x>slWpLKj5tFB2dENiF_NyMVK!GBku`XRi5gKG>^YgF6#!A2j2)PTGB^T>H~hbJZr-lUuZbuj|u-CNt&K z*l}1l{(es9pV3C4KI~_NdF}vBOv}**OK73`hb*0+m1Yk96s6GErp^p8*%B7A464{Vx;su@&;&2Y2 zwz4K_?%6^yRk;A{-lHD{fw@(Zl|2AO$i&qLm2xe*f|28vovO17<<#$WC*t6?GV6<|+ zWXt(CdFCw*(|lvLMLDPNw5=+UuvsIKsPqK8l}?E|wF5!`3N zEoP0(CcY--g>`-IpAZZixhKuCgxIU7a;~L#THEWTTh^V_&IGA=dW)$)jDRLW6nx#)!}WTNn2Z;{1? zC;cA&16Aj`5n`;h^fdOWbSq!vppW+_?%87XPO@|LxOR@iQ|sVn)R$(?Oo5*B8Yko( zEw{fZkEvX!5>SH>k3Z#)!hJ%qCb7*SrTk=x${dmsyThdb9C#-|3JMW6en3#`x($Aa zr}!ZiADb1^HILV#B4e_+Rm|oFCoWk{hhyaUTl=i{+pRT@bZpPIHzq{bi?FAg49r1> zc^=Wnx1>-|i@3FDju(IEE6dOK2p{Ssp(vZdJYkf8tD;r}};1-5qn_ws3Z=yid(mt{P4yd+2Yxh$UGMR+6~ck~BRM;g6~!=FARDD|Ai+C?DXio9eP1mk+pu)Z#O+(tn5 z(b^Iw4rJ1}-rNV(oaJjALP<#*FwCxi_O~5|mS3?7dIU5$E|}=K<#MhYXVzDw#{;9G zEGzpO1u`R!Rg+PJR52yprvN;gIWp5pRu%Tr6B*cOA42zqHrLui#2)0Ot4t7ePwiB_iUHd}5S70`OGWiObP{BBckDUVq%GRyn>CI3_i|F58kK#@c#w?4FmX;9Mi) zC^wPl1AL9psq9FDm~eQ9a8J+#2;&<(7eAtj-bVhGW^?fivI<5;7|p=Sm!YRyzWj^| zYP2|NMmUS=5RWo;gjM|WMHrUn7kis@l!*PrMIx{w6j9}Idr}@ko!Tv;`#oQYqR+R7 zr=m~ACBx&3qHp@RAa?#n-6;Y5*QA=3^-=aK-u4v!TXHz)n%qn_I6>N|UQYxmW~&@x z;}ooz28a`@h`&}(#S2z?v3JXubX8hV2Lz42Zq>T6LBoQFye=tN23kt0Kt6>!N$M=h z($&DY)o-+zB-~<1i39}<9CPdB)FSo#Q9b7rPvMLoZ%x9#mDmgP#9D)#_6x3P@r|zYL&qydKtnbYwao5MwPx1e-{%nA7UjWw@&>vp)ogShT31Nt z`4eWus@(f#YTnK(yGfz}3%W#SlTl;6ZGU1*(_D`z&UIPaI^wJ*xdNFs_=Rc>Gvv3M z1?j7jeBSOph@13b3BQ-f(bV>&{eOEXjI_()Vbts?7cDSRRPs|Se3vokbSsH%ET!Gj zY-M&qiWeX`TK0Ia>)HqBV4s5x%8(O#6C1enAXQ`@h${J5D+|KckoXbCv4!ogX(Y3H z0J4xlB^80fD-{#j5iG}ZM71~4+)-6DNKNh6>sQae33DPHD}w7tK;*C#Op0wo#Bv-RZaWf&eS zXGEn{EEYX=PKdV5&&8tTex{h1IhUk)%^AD%2EChLNrrnUH^vTRAMG^r%HU?uVR5)s zZ!;(}82$6EYF+-ySkU}?nH-S0d|>ha5T47?j5o(hWBsOLPU){gn&@0 zxutbnH&h?~+tJusl7Bs&k)6IV+3O`|2(v-B*ue+VXRIpR&UB{m7dLYZs9ab_%E}ou z@~_TEp0d7eoi7`mgudGg^Kme^H?VX;<0TJ)4KPf}ohGyGZ`F~Mk^l&4Fhd}@d&siM>WFP%usAN(j3v^!> z!xjLXiD;aN$bSC8x}8DvQV5HYD~~tKahNm)MlsFo441$Ymrvq18l9T1806WcJ&6$v zg{rSnu24{NhL7sp>-Y#W6+GOC*gb@v54Bx%EF@PU4>6n}!np6cn)#F`lG?}Um0sBm z)2v_?F9UO}qozr7CfgSL`>2=EzQa^(-7YZBn;X-snjl&B zv@JXQC0iuQl>w?gIaBI@>jddm*8Ssg?AK*yal9V2)teVMXeN`p^YwEaUtdzvpIC!q zR^=%FX1;3GkS3X(g)I2PQ+3T_45`2F5<;-n7n*eJVDu&uVF{KvJ=8&uGpR6LAwh}^ znAh3|W;s9d%&8^gXEICY`uZ@R?coW7XLZSGY^s)e(7oa42WOPrz;;qN7w2}SnpB9- z(eB{)L$$-jv3urdlQN9j3Ft_s#bFgU=oA^;y$c)V?9EL1Od*?mL{X%~#(7hB7hH}6 z#CHE3VOX>ZZxqy&zG8JOas>q`Q9{OE zn3uopBCOd=?jcjDC8^&qzMwI--He$LqPFQi?|=vfRE96UTHN^W%*2JI@vzh*#wQ+w z3c3(R7zzB%oHzIKLW7gz!Zre%#JCo)+6tsS-O_lZCrd~4QGvy`Od#^DZr1)I`s+}c zA{6oS3o-~!5;lUedpE9Ot=p>*iv$_6%ih1?i*;np>! zE#t1RKVJ$RZUTlv)|UEFm;yarvvxuz@^HtiST@NYg7(xby{Z)^+I;&j*rnXthihTj3Tx{L%g2g2M>M|b(AD6Ik`L?-$rC7u6k3Q!pC2deSizyZ`r*` zN%6(Sjv1h(LD)JV^|N^MJnXosXc?MqA6T02X?(S{MI(JjGeUnhE$^`VD)B5o{9v4{ zCKsb4_8^(qJ5o;SEeHu`IY0TZC8Ms%lXt^WGQ+X3QetaWME zZm0tNU;rOH4F=!7*KAah8lqIF$Q%$|C751;_b2?*+aSMv%(|O?NtXNfg#^De3i{rim?WI^J!~n|u38e`(U#3oJLv~qXZ}qnQzBft z3GbHD%e46w7nWULvB+0TyFAskoH7Ke;xJC(H$VS@2{_lhMJS!S#;BY z9Z@n&*r=om;8Z_blw>7DqlZ3DJsK1&77X|L1A7sQEc?5)KWe}^Cbh_G3Dv{VTWRp& zV>SEXAg7pfkKn*Y9_3&$pyeEfc2A_H<_IJ^!`_RS4^VjPibd9vtDR&-KSQz+Z7U15 z^-m0082w~C1e}=J=Z;e4s9m|DpU}y{1rnIz6%&U}Hn2_cClJ1@%cbbHQ*A(XQ!BnC zSYD8SM`MKIV7R2vW}}9C78kC&q0>ZQ&##pqh5nOHM3esgmfRsGxqFQ6+0L{vF9Rn2 z-o1iMxsRLpeXWZo=9!^7auXJUqB{b{mq^zI4*cxPj_G$bF({eb^R#~fzKN;|)*fj%`b$?JTo6HBO2UHRAt&pcT zP=>tn{NxbWC<))h6Q429GY-=0{>9kfBafQ9w>PNfV}B*#*j$(<_oInz8e`8WFnPR5 z_RJ-uvk)Ux)y&Wz9nfVpp`lInLxruX2zXE0G$=;JUway2{ni=C)DOMIU<1USi zbb#J>s9%Wp#cDCxR1f5eWjmdXCT zV#y^7YDLnhFJjg912=M_y)uTCHK9&wMbz(k9*UgDTB4E^X5Uur5yfR?4pX06OI*QJ zHcV*2o<($CEx|Cw4Yf|$A}f8_pUN;sww@gJT3f!sjOO`yu&2Go6~Ydodd>ykB_8>Z z@8Y1-*1>R`v_Rl7HNjjbM8;Ox=B?*Q?Pv@?S@`rNB0T3@%Hc0cewJ# z=iNDAK!ECj{igv7<}hFFZ}ppXg{(Kt25Wl;!4^Q}B__eB;em8X8?#-Y=NQymUxp%+YbNJkrM0@h>k@+=ML80IAH)eyUg`QIFGX z(hZgaQOI{UP8C$Yn+{R;LG)X-ABudw!%1vofXIeX z?mRDWtT|B6+*Z+wrmL*lpJok##!y7tC*Y2BJq9V(xaH{mVyA+qlQD5KKo*3)zMcR6 zN#M>1p?BRgD8NMUi!P<5zjIx8tx$%Z%B0^Y|J&*!9VW2ExIDga$PabVZ}BN{A9 zpyrM z3am?6X)MVG*)ZDMEJLQH$&EU;8T2ao*VPK^DrvlCUc`0`MNEiDNvt9v0ao#z3u^Fh z76~k}&c=?`*P*yE;k7qxK@~BAfY5=%SOZbz)n=5?zdsyosXp?ri&@8j5XRiyjvqi%7iI1~Te`hlG#>suQouwQcvb*N5#6*Z2c4Py$ z4r!tOXn!P)Y)RlN4qyiMge)EGXRsJ977!qsN_2)(!ceYN@$CdG;%0oA)QaNUz0Nxq zr4pT{>L}w~sP`qZi;8h#EN<kZlZ!_uY**V z+_v+HFxN6;yV1}we4G2@s7&+n<*kOh6Rs3ozt!Z%UeWZ?e(|7bIYDYM%j$YK>;JQV zZY~j$2>W$fdk=@pSnmRuu#p-?hyZeSAcvt_UuH;SaEe%X_YizI!BDgqY~;B^mw#e1 zJYbl#QV_ujQO7p)g70Nf)y;1p78p)=0MR2k3TZ@a)T9QJSy#?6e) zk8+4?l!5@=9JkIWE#LH54Vz4J3IJsK^@jSP&lpNdW-?D4{_YgxHIXWDXU$Rz5IWw5 zq=If@B$$nj44*6v=)3KvOnt*LzZS|;hDiV~L{bQA_=$~_rXcOb1kY!=s%y0IF0E%N zsxDRsPmfdQ7E^7eCwseZ(H2(V*eSlR+Tpl`L36C0^gCW(quC}EE5}#h_f!SxFADt- zvSnn)B&W|MHbRfKLz~#4U%y${l;eAyXuLR-OAyk%Ef{Bia@Lz~YcCPn6h~@w1l(fd z{dIT6Gigp;f~R?&bSeL-F403)L8m@2m)@SndAW-emD<+czHQV10oQh1j2~3Gn(eD7g|_*5MS;qmaRbDA>7Ui|FW* z0#@tAvmwN{9xQ>!w(d=XzyE2)49`WBuD=SoZ5Zo=GD(p*6J4CLc}{)RWgKzQY>J7R z8Zo2{OZzckpjSW;#ls|R!?=hG4Mwttd)&Mha8j%yu{>2PMZ_| zH#?QAYBc2PCn&PzHSLaV`f+w^`hwNira}a!9=#MK)CIAII(ioML(qVJ9gAIgRzdeV z8WU8`pw$#o`?;*Ehd%1Zux7Gxfx*GEFKQRuQKVUVmW;5)cJ?39WYzN~1VrgyHI2=W z`XcjGNFh~8)qiU7Y1iib3DCP8lS2m#ReH9<`4_c#$nl6uqochrOpdlNErTW8WW{<8 zQ5~iu&WX>yZ_|-$xqdmGm|pZf#4uS;43fx}<4c9;iMF73aG;vddAl*oMuqq)G%ArE z6>3MCi%vw;4h}(Me87FX;^WZ3(+?tv^xh|nt7T_4wLv7+{2iAL8IJTE zI8)gM%c6s1?zZ-GbiIY_BCMe!^=Z;e;);_?w~h1fNpMG$TZkcjL(e@tYMn8Y9zZft z*V`N;ca6nB#ZA z*`9VEp;Lbs4wZW5%$_COMXD5;!WVEHqt$wc_L*~(<$0P)*>zB;9ri8H8~TLLCIgsXD=L;uIPmwQJH)-MN-;vrX|G@ zL-rMH!3vZ-^?0np7u@aYv+o)_g#Qi73aZnFooAB(o$a~-?Y5Dqe}k-SlF{b?u z|8P*f{c27)ZCu_S(6$2e_toIng5S)w$Es#=t2flm5sQPuwS|en!iuZ=lhX?&f9ufb z0!4|fM6y(yK~69;DFrFtvo5<;&zjFXB8!a0Yy9c*o{uLXR$~8<4yYjXz8TXk$8%Y- zuK>{hqixeaktrttC@qV)`Tk1E9Knkz2nebIh*;<5?dhnrd#$v`R(;W{5J#H0CcVnT zggiMRM;u9?8VGtnl~(kkGs~<`zP9!Uc2L7F8#wbugbD+mDb~|HDmbWg>A<5xT@twH z*53O%Im=Cis77aYq^qvI@)|JTgR79B_nnjN4^vcx&gJl8mo>WHH`HOZUtSj#N_#tfjX`$X1j+Ooaj9EN* zn{=}4s!e`Lzt@+7_}zNPf%7^KB{97ZG!Z^;+rnLIeM$v4=M;{&|NimhSiSARP7)`) zpj6n;cygd>7bkx%Dq~1Bij#eBHE&4O<73f!j;JysDzwvoboFpw^D2w?q099X*TH?g zB{lQRga~kK1NHLre;EEr`bsK6<)s2(J@xwY06Z0Gyu=0>MYio`%jXis;&S5f+FLZp z9`Qc1LC;I&Wpfm72JQuRwK2xdNZI_K6aPO9$dp*+?Bq=!<3=|4^{+hVv1nFebVBF?65 za$)_6SQ(Be14MRWQZ>kH8*r5?+ioml0(8ysllTv#uM!ndTy9#`Xd>dL?AO$#$X;4# z-=xj}Ty->KYJJBfJ&zhDg(BPd;V}t>md6QNRUIS;+m4HbMeTVn^}>YyVwGu~tvxFb zbc!sN9UmxFSq|NWR*d?sfp_z#4_wiVTX!5Gh}ic$&tcF8lnX^&o#Uv0+X&Z9?>v+YCz zcCqkdoOHH>zK!bCX!SoaG9}#uqGAcw%AF=kM$!!fgvd7kb$mR!g3)d$Tf{-vqIBkF zvd@ZUnTU=JhtyFiZTVw7_OcS(1l9pnOnhmr(2y{UB(I>OwW#&l7H2U0CF5BJ6MWt;ak61Gn6ot+Uif zrp4~6IIzzH)}M=!HtRimFS|vPv|w}9oKOnQOGk$CJOh$c8ghGkbs{4RS|$wTnKhE| zx95s)BH1ExNZ=RV`XuF<5^*kqy%u=w?oerrx(pQss%QIWmc%HsqlqF_y=adwk7;GB zy-0}W*j0qJXlp2FeK*&&*(r^2is^xlBk-FOe6QsMUqGWd z?`&xw8vobBWXSci0kX7W`KB< zx~6FJ`NXIw_A6_3JaVCc`VYE+UxU<=yKz3Xu~X6wB`7%LA7&$tn)U)mRlur-O-gwm zgjUdtCyO)-M4-lF|#Trz>4Si5-nWu0$xTGge$)|#ihqtRo=GaK@30KH& zOmU#;UQ-2r-t#$p*p6ZNZJpT?xy9DhHeHqsfx{FuOi9i4ITP+%>j$sREz+Jm(@^av z+b<*HW#tc8JonC70&yptGv}%FK-Zw#;d(R)ylGN#00GhFHu3)L83-(>&;sl|*U|~} zvZHHxf2a<@?6~3}&bTrKp7o9nyX4Bnn_TuU!S!q$#FXbN(f6tLBqL6C?{p{?fS_#4 z5(vh*fG2YbbB76%{E0q zvMi$)IqRF6PRwo&3qo)X&Me-%^mhyU|Qe!%tb&b31f%U-KBIXPUHpMzV+p zzG`NEi5Wu&eA`6cD!+K%$*QOr6V#fZLM$E@{bf5o^smrT|Sib|qcD}Mf+=zU+x zZk90<=zI4Qopp;MaC31{Gz;;{W&vgDuGt^rP-8nD@jx~PS@0lb9UqWj!+s3c!fA(m;nr-pnasc6JP$Yk3 z6U4_Xc<4$4!{O#%BC9-1fGiso0KC^AnYIVciF4!hCDT9;kZ$q#SO3BmmZY*HPr`Ea z-P@aEx9DjW?+}#!o2ltwLRo~riE7l~V%mdejkZSlF6|$kHKHC$uU+K?#_{`7&MvCP zI642?XA*IYT!+@WS-2u;=fLwUKH-k5R&kl_#>m3i6_6zQFR{@=&{^8F~27_E8 z>5P$O{0oP!%*?PuqF`;T#l)mWBI0sO2IC}DR}X`=UkRIwn%pr_wL68R(TPD{k_99$ z$T^W5W_SGlYF{PVCD#D3kDTeW_A1gA-|S*X2HJ{lY>WxW>UpMIj^XvGO)EA=E>c`D zXuBpuwfPdP&cnflfkcYXy>`GdblhGHB}R8I4`jsqzAM&F#$Vw zPwLRB>es2-)Ge>n$YCpdM+(v3gLzMr@_dV>p=^ov9+3KKE6H7%OG&R&q7BzOn<;(z z3zweXG2#?z_@A}Wo{N_Jo2~pSs*5bvvIpn+SH1QOJSQ+XIX&c+ZXop@Yt67r_!zOz zoNTF-1SyU7+Zt^f8xwzp!-)itdZM1>>7=q0J56GD5OmT$x$WR#v7^<2(KY7Yc!tG1 zpP+dWdsQInb)WAE?O|}EyD0RB(_fG5`_S}^Q-D>9Q>hbronCV5PB}dbgovA8kLC+S zgZ=1zkuJ1yhv*{D_gQ@EpVj2A!J%MUdq64&o2sGaa6y-k0Lt%Q6I@~h7u?9aQObM{ zsJsM84Q*w+3~m*m$!I&_R;j`R>$B0de^-rUrJaWbnt;o* z#msaG{S?(#J3qLmr?#qIeCc&w9JM_6R9^m??IxP-V*Q6(>Ys~BpSmM;eLRK|Y^~ko zCa+o>#eRWHe^dX2=)>z9yQWUHh?+`Cye;`#9Fj7-Iix3BA1T^3CP9L}sqGp+Z?m5X?x(aB!-HBd*TP>}HYi;SHPtb#_9s@j@JU z1x?mMj^gG()8_j&nClFtUEXO--_mh_EA*eWD@YrY3g75jCGi*|2GJPvSdi8=3?^(F z8aaF7Df;+wBWI?Bu;C~d@R$&<;Bhi>QieIvf`}}A&-xAs@NqXKwa@jIZV!T)y4a%n z6h4SFwFnRbl$Acz0olDskG(!-<>)Wtw)iUTadSXIG1@;rJipypHJ zzww=~ok~**D0*K!6k7@?>b&t;Up*A7=2PbWdsQ--&dy1Cb+<=_tZ@DfQMAckAc_+xvLe*$b@EMEfg^xA3-yvt`;Ydm;p5+JS^8)+u3f!f@wpn%u4gsB)D(0xGwZzH`nf*@HhH4#RX8>ye#c&0x zOM{^1Xh9_<-d3v(m(Gmm;?&BTd|W$uul(x&1Ix-kSSSH!A?MiQm-%yx*@ zL5bDX(fceeyTjuI5Ezbv@BKL(PX*9vvK)TR$zOAR{{xoCc3OGO{{_o>-sZE_@8CP5 zW|I=`weXdX+U@bWb5Drcl-7h5rt^_tHFSCFcMr`B2hHAWqw%+B`UhY1jE+x7h641D zK`D8<)Y&`qN-K0abF2DT;_F-gnI)t?PIxgiJBj-9frp#iiA#iW1 zN2M4bgT`t(QD#DPbZ_T%VQvI0-Jum7c|s8RazS83DEn>fEe=;9K9`f++Ee@G<%&od z+QJhVs&g#jNChDy)66H=FyJdn(B*y;2Qc7;L_8zX7s5XdriFs}9{SMt1h?juSaHaO z$P%I;)rS5X94km47065%0*=btD4zhTMxPhrXY?_lWwcz#ZuO8d<~j^sD|49MC& zk&dbLTDZ5(b36MlHhAv67V2k{6@2p^w@#%Qee;_BEo_`hmkB8HJa{eG{$u8YuVm|# z8eKrK;?YaSa+TM$*Y`zsbTicR@%;k*w5AcU(8q3DG=j3Ga{7tiAseG=Yn1=!a2G;i z*6S9LHnCjizk!A2|2J5||7W!PZ?GsqMSOpGe?l>A5(pih-aW+fXLJ%W0+VVs{@@QM z`>(Y@C*=cY8Xsy-X%LDqlsTCH^&6*VEp zRa1*YeT86eA1#iNXAPj#Qk7lV8ELF56%%TvuK%2#^p^qgnyC)(<$Q5vynMM~C181| z$?0{`iCB9}j3elodUbJ0$_jkAYim{N2Q+EbO*SR85IR99 zOhv;gXotcEq0#Z;Pb!?WtPP#GvS{Th;o{na5aS5EJ+_C>anQ=of0uuDo-=HC@eQ)X zkEq70$mWBG|PtN$$yU7syDY7J$z8d9(-N7C5#j?hx=f8rM zwfzaA?1Dr-qyyt?OIGXq)i(F<(Sf3GCuE9m)F+X<38n)gP81{h0tX;t%RlOK*nT>P zPq!})a3l!|5blAQrBuv3rHdjB8jsl3gz2z9OaE2F45{%iSxWP8ax%O}_J-UfAiRIc zf;mw@JEJ)LB7X}DFD5cP%XB#q4VkDw=ppfs7l?Ly?_A1pJK$@EYM*C0k{BiC^hR+h zN>0Sh4d1dtcPVloiz}_RI-AG5$;*%6JD+{)dsXGwo4wuS!@grzl<=QUjuOqAB0Cx< zBUYq<_hO+r8khUGKzB5LmPlzTk|&38Z+4$Z*$C&wB0i=%BAUm7e4jF&SZ3$a&H8up zrPr-X9w1p;Yv6Uw^Fs7Kx+3TXIJg)w*gZ7$8KU`nhxm5e8Z_^U`~}+STJHMa!16zw zQU8H=>R%80|4bGdkp@%}=QVrv%4Gv$=549O-$)4m)x$Cz{`VecM^S0x`9G6o=Bk8t zn(X7hdYG54L44_X0JdtTO%A_ceR>T&XQ}1OI*;MMsf0%3z*0Uv8rFs$O6vy$&b(m1 zwXf_qR_cUplZMWvh#m(DyrtF-L9GeS#;LS5`>1yCUU|=&&6B7o$(eTg>MR=D1SThh z(hw*PeDf<{=>-J29i;xhWT~9=$7;X1w^9U&;UqlW!CRf~fnP|GH@rG(zY)mki7x4C|m3o0z2$?8K-G%{i?n({8z&k9k=wc9SJE1i*aEW)LK%x^IJ;J zTc$gqRc6xZ=%dYzvMzetLp3g+N!jbw1V%N>3(XTJ=1j1Q`siE0<-)UITy>#fV@PSV z@QVLevLsSu$g!{;fbgSvmk+yRR@tg0PDzR%@7i-(o$iB7a^c91n;J>GQ|%EO!}F1L zfy7%uBH*EV_=V?g>zt*CbmWL@dR z$R3E~I}x83uY#J&7c0$(09{JGhJULPJ4IMgpHitavAG@TdcE$YJn2h(WvawUKVLo=M`*y{N zQ!zy~w5PKE&cjna`3p7z%v}@E9~M9sIc?90B1>xrta<3_ro?lo;|AG{AHoKUdK#N z*iE@BB3@2g2jlAM+fq*5gwGZ;-;c4ulMWaFXuG>K{C_ztEdRH|!br%-$-?>HS(pDH zZA=`T|2w3Og@N;bK5t@L!4)zuG3cT@J5g~Xz3&f(btAPMpupV2Kty5DXz7Nxx3{|m z94Uvl>9uEecuxW5H`!Apo+*6R-PYauLc;k~BQ#bJOu$kBSJ~<7nrm;s2QWq(SGYiI zY;qWEYzQRS*sj#(+IxOS5-b@4b&2R>IRJK8M~1nzcU3aOt1qiEpa#gXjx~@qPT(t^ zudA*v8yg@5HntuBW?DwFw*KSSDYgGj5^&$l z=;-8ADYw890#pkVYYQX=Cbu@owH|W@_9n=ZK#7`wc`N`%kly0_>Z)&c;^O3F#K`7! z2n0kMikSg;t162YxI%!Oa1H$*q^;1zzn~uP?sh>V&I0HnMNQ6+a!KH1#%{!ba8K31 z+7zbA-OJUno*gt0xON@bis=D}6f*Byf8^o+MPJ$>{3rS{*TK&lfIK$wBX4f3tQ?me zRNozz+zsBhHG%OD(w1QE=;m$)g1MRbZD?V03Fh_8?#9~Ez{=*y`j*(iC?KT*Zt$hG zzx&LY9$1Z=m93FgWdkUSe~x9SwM}VaM}=Hp2fohEj{DgoHw1^s=y}-=dcGZOu7_-2 z_x^@V*Iv&|2PlT7M}by`b|)9YDu^A}XR0GF^fJNbG5cr6#KfeAAp*I80d33DY62wk zZuWt`l*fO<-kKo@=po}k`@Wjt@?w)Y@18-&C&$;&p&TGOfqc4r)&Hem8ks|;X{K|5 z%J^fby+{DW{Ln$C0Ry$Ch%HW#XARwd3Ap{QV^{fipY+M6;7sf9B)ZTeaW8)XGmEe6-Gb1nj9jn(&&7R$SS$gIV z^5}Q2o#X^-=xMd%+qczx}!g)*uB4c4YynrTfikBLG!i^q#4f zzR({4*IE4pz3DMy0;2So)4u*weu93^AS&1G*7jwIbD$Ve|_A%g{WwziUQU>+M%BVf$AqTK<(9H-ONKdd zshPw4mTQYSy6iyCT8-BA%fH34zLPT+dqchh{A>FBP@Q@+xV!Z*0bE@pU)8L&E?Knw zeY;+d6RYd+Pnm<(&2+u}t5&*xLAB^@->{r|-G0&|_t-m!@^AWumKPupy?S$gdib@@ zp9Ej0i$G8=kQv0Z(?K%efz_2k+V<3<5!-3*BOzuMZcPbTY27J(wsfx+cM)*t=K=hE zs|69l+nCha2~X;`DdV|a2$@#3)PK|Yr&)Yp28>R&!AF23TXt%2eQ@AV!ToKlC0dII}2 zvMrJ$xWJ@Y%*>PnI91B-PwSPJSXEOIzns=N#7J`W6|>&;xGr($-JNqPi!X5HvV)g` zxxk9%)HMo~oAiu6B^%yg^+drL8}j49Pl_NO;RkHbM*ixkqTxvg4*y2Q`3(jc3Vbkp zrmdXMSVEP_Vk8XNVwHXkrlHB&6|yLQ71}N#M|JHj?~xO4+IYT481IX7`rGtxT~dyR zcEcXE7joOncindpc#h~m)(;=wu4Tu@+pk`C$0%H~^_dP`y^)(T@oR;yR&zd7)P)x) zeOLNreq88Ed7(HsMJ&WdZ6y0mO<3(V)6US ze9O48hJd}BZEm!(XK?Xnywp9>MkC!l6_*OuUYk_jsqigfF!V4jxnjEkL;cV+=#(*w zau5?jinff_g0VFYdP<(Kzh#V52Mu>(=}CTFZWo(R;zyv3FpP~Jx0LAze2rjA51`eQdpk4g)lm1R8WDdi3D5}Q^+V+htJt;QHkPx- zF-PabrY+d6+r+_T`|cqY=l*{CMdc7G<4kxzq|j^nIAJjZ&eK10Yhu~WQe1vfxKjN1 zJaBPV6u;q_c@PvhSYZSj3S#$*`SM^EZgxP64wrq-|0pP2`9cHYY_J{>T4XC;kjGOp$(#SQP3ILQl4mK@SQ?;G5t= z#{Aci;c&Fcp6LZT!c5;%m&`B?yA@U%SI^!IqV~|*bazwc?JVm0#@4h5ffs{Smrz-r-w^V zAWh^IBI`2*QmL!U|B`Qn6rkdS1-&?!?5^5rI1$UY+Q2L_04I(9S~1IbTQ7K2Cs8W#z## zWfUEMrzSnnhR`#a3n->ChiQspiDV;9Hh`2iM0>eO93GK01S9f*4Q{gqugyQY0sl#I zh@=4e9dS;#-J;yrLmHczO3_iCH>cHJDZfF{!4&NAgBX0yj=UpR0ITntKKab7mr}0` zmL!VqtJc^%dAa#e9QnXJ^ar&<{-arL_96-7RnBdS%4f}yWL*w}P#u)Pe)8k&UhEnH zW%`tBOG+zobh-@~#V=^1hHFU`X;4`_WKF==E>`xww8Hp;b@-LNOPKCKs`^lf%-6VQ zG&Z!dAzc0-fQdM8%ly4=?1CakE~HtUkM2QC5+>?r_&TXe|9HbZEBMCd+rZTyn8eju#8%jrNkc zf_^{uv2$7R@>^WCa!;DWcNlygjK@pjjB?4S;=Ws-M>WDKdlD#9U+Nb&&xNCN7^#vi zZTrDR=%2JQ)4uJ(tHcEa-KW_u}0Wx@qt125^!N$cnhd$I2?Q&!~lzI0VsYJ+*> zg2CFt)I6m9f}~1C(U~YiNeeh)5$S?unKp0{u&?&2#FM%t2@~`wI1#^6TzY^J%Au~8 z>@kq^_#)A-5Hk6iD&B{|MX+i@W%4DLkC9W-z3>1CeP6{Hod{5$W*!4)Jb_vc?Mh_r zejV69mY|=ezFh8tinNvwZ$);-QRG`Pt$N=-77(T}_Ed440sA$F{lzfliy_FPEh|@6 znUyzr^N*S3UCL|bUD~di9J;=1N~?|qqjB5v#9I52t?@8z_8E%Q=!VsDe~+i>r;5!q zVMXJdiNsI^Fb@kuM~u-lsmn5r__LpDc|e~x?iLNCS5Z_nmHTu&!#=}2U|vNfJ)Ds& zVU_HBgUAK!IxN1Od$qFVjv1N41jo)oLOwtoLdNo(svPf-KH9#_xy&pM_==#Fb*2u+ zl5ylLbN{$X4Dfa=9baL7%2f!08kVJS&RfHQ*vi|l@ns3)sN?6&IG%*v;P zv=AldHOw(6SBdKhT0Jrx;F8rX-)kuuHpW@O*q;&8m=$a4oIXxo)S!5D$nQ_;9^8_l zWBk)zRV=@LyRBX)N|+2^NbaoP3iaHDH{iKwyB(BC-K&~a%ochKFPzSiHLZl&&btNrDgmL= z{v=hEeJ3-L10>qz?=NFGfsL`ji$X0twuTtcU=pFo)lO5m?H8~R(H%#l7>7lJ=SFEO z1h2x#kMf6zQvZBOBxZ@N%<>m;Td9=+-6q>V^_*j++t^Gi>Ia2vV2y|vX~Krvy%m5j z3alAnWAY=WdQ56IwDsB|hcDZgPXH-dJ-kO#LbFiTwOUASGp^IR!6HiICEB8dBnbKW z7(txXwT6nRHr4d3@>0rgr!a-usX625ecPiSr=&E^E4@9VPq`L)=d`{X9x-)w#tyPcm{ zPD4GWNNY~5TqVB@eko!}2o{zcTA0NjQu_d(L<#e7SQ4;WF&Wz@Wx^v(2zAH6ZbxWi zk0=lSiUooy&mHf#M&ND6HQ|uW_4YB@saigWijar$4lkm@LJ%Biaq{W+I@*<~Vv66I zTv$RhtIb{E>1H;BDS%4^m8?%sAHqgu1rYzin$}@HO<=>MZH_2?-MGX$)E5+zDEHP| zG>4dAqsc%b{hJ0c6|tvg%J)|bVVi@|DCYD{bn6vog|pb_TD@{)c8%PW$&K!zF0hI# z6C0eLeSRrN+7X3M%izfTq*ip{gyN0Hmmd3QDya^ui6wGj609=~8o+_tR&Rwu%4Wll zFe(Zni6vK@wxL5=GA*`~u!(cL)k(KE!{|^%<|`kuTT;R$bljf#;Ke8CL9@O|Q@fhz z)V=UlEE>7BZ|@x~a)?lAt;ikah-Nf>m>Em@mnW)I2#dhpz?fRk=OAFGOGx-ZW`;r1 zSihE)Jh^5FCZNzi{y_1BJ(#)k)I0xh&F#rHeM^droW#F_Q2CDt?{$o~g5$pj`n?{? zAZfcQ8A%ays+?8=*-%x_ww#Cm37p7Q!@}Sx5a6Lw4FVRb@|3K|8QY9PGv^nRBl+W`45x&3^*(9yF0}c1NIyvX(8StW`pnQLxT=34i}aYe6G|tr&YIl z;R*Bi9}=9C2%cj!Y)187yn06am{^S_wZqGFvfE>d3dnpeTghpp@!Rq;GV0z7K_lC{ zW_CluoF)XOmfYZILoJ^LcO^MUEwop?ba*y0Bsn##*;Ku?RQtpha=+&3kg6e6gW z?0j08Oz&8YF%&IFt~m{4V3pO+k6!jY#@T*H&4 zbeCDOq;v}fY+1!_iOZ?kT_qF}r#9uzv5(ss*_F&2sI{={=(=LrQ0s5Fqhcf@B{A+} z|K+_zQ*F}&EBl;N=-?(d5*E| z)TNRVU=e+b5=&3Rgp?S01HX?n&y+ioh;D2+kkYi}$0*gg^z;H0c~h;AX!^k@#O=i) z&MsV$tUE{GVk~K<6nwP5jAUD0j+@M+5m*~|glCCror%NHnT4Ed(oKL8`;4iFcqz2^ zKSsM7;1{d6=HxWQ)U@lXDD`nIX5(;9wrP&sMAuwsb!=!CF&w5yUIZmLe#nt~?PSTA z{Ums;0s@uHQCyehuyI3Lby0f1u*r{^v-vziq?eQ&iFP3*J+S;18!;^MT4qNXaAt~d za1s+mBnzD1x`K>&gx$K0DE>wuj`P`vhQ4roSff z&hCaL3zzJWWz|&8!EcB-sL&u^Zg>mq4VvLPd4}1RCaoGVqTaZE*zpmdu;C>-#9b3f z*8D9z?3DW5`Z#)3a!dg}~7@NK30H^5%6HKvfeQ!h1?l?1tV&^B|vVpGyD zxrlnlD ziH>xIAGp#)@O$$UZ*sDngLf(Plhk=e)HCND*xPlJrM$FN8do*>g^Z@*n!8g#9CN1q z9%cO}5!Y^WQpq;ok^{z*hr&qr5S7Kjmm`sr)1O&>DF~7!!CJ{Yu_= zrMp=*Zyw>SfJ=e4GbWnnDW?9553Clcxp+t_FOPp>8)`+LBt3vggCVvmV#KrHEg>Hi zW)xu(8)UXITJOrCJ}1+$DL`9=G59T`t(|PY#v|{bmRGRn??Kt0p+P*e zo+OTUcDgJpirvME&H>u$7`U7_hF{B~HQpfq#mOcF^mGS$(5Qk^Ur+&ob^9e!B(vLo z+yvv?Zm-66^X{K!JWJQvAqMmSclxaqQ@b4xpI}Aj+@n8;(RS>!oUgp#^!89Fw=ZYO z2pj$5oXY3>mr#_qhIEi3ZHS`tZy*8S(f{E7F2<2j=3M#YuAr{_U4%vumRQ12NG);#6JJnTM8% zXcT@?t%;_5T)EG%WFe&$yHA5c>z5(gkyV^1j>}tZBh+T6!r_4cA4lP_64ko(SG-m3 z9UnV|c18bT%q?9f8*j1Ik=C+64=s@fU-|Jodz&OjGS;;v?KkdGApQfHs%qWk=(`#3 zF*HByQ~s^T1TBc|y6~A&HkT1dFi$QsKQvrX$07M*M}$FdE>x=o`;9p~g_qz+LmPQQM*|)Gjq} zeP=#j%6sB5!_$`I%Oo2Ia6z>UgUAuqRk@VY8VBBQRe`Hvj!-N-XuDB3-@RYhC-p#K#6d5dg#008HqmpfU!+G zYMHLyyR9(yE$YaNy7Lhl|1U>RB_E1;(ZCjEA@J<lX!8%L|c3SKQ*>R0QKnwiM-DJhI*=(A|!3k*b^-~8Kcl64*@QjSOml&xM z!coDbd_N^@DqNW52M6N5T$yD2);L4l8QcR|3vf9ML`O?o%#ZOs5%0*R$2G%|Lwh%0 zRp)N={eIZijZLctcz57wma(VCmf6Db>wS|yTye36Lm&f`ZKyPgyV_) zg|TAu8!nC4)AdoKMXr=}Ea5}xmml^qw#kFloN0I%cd#Vn+s>BehhqZ(cRh`>SoK+~ zFc{;^YyCNgn4j8(=+<=zI&_t?5JMG?BI|_&OnPqwe?fG3Eu9$dS<=p)ZlBF8U7k$H4{Vu<$3DIJP@S&`vNN+*LvYc=X1B z3hN4CQOco3)75zu{YupNV{$l-0c|kf3qdRu4Ya%lJ(YWPHT*G7cWr+({@yVCIS5O_ z=g*!w%yq$!7i3`7&7Sjd#Z3>OGXO!0s=QTAI~?MV<#S*zzaT`XY(FSgV>+xY&c;x~ z^unS}y?k)%a8LiJ6NgRQxzfR*E|La4=Bql1I=wtlwoPD8``TXJqzK47{bV!-hJe0v zeaXQQ{E7cQWm^82lwhLt2s$W+w?c#V9n~);xsH}pbpl=!5dH*jKDny)S31g6s`EWt zN-5ty_x8rV092pg&!(F%(OeTdMD)<7pt{R(%3=j&OW;410uCKrWxKlIz?FHuKZJ!PB4ETGU!BlOy(%nhOvPXm0Mc`f995Q`xCvAdm5h^09jA=D0Q6 zN9aS(aE#ld;w=?cWDV47{;@LMxtv(_rl#|FLB9kpOBeFu313-p1C3aVy9YOy9=nB5+{ zXgndjiGPrL<539|3WIE3@1ikc1u`U86p{1}FPdZV|TTN=phd{{)8?IkD%^xW2 zL04b}huT||z%q&0@j?{||X8Cd8;<8A#QdRgy^;-=y;BDf13HW0^5V8wL&+Z;0#Zv9u5qWc!%uQwCrUaiY zQOu1QJ~6=vcEO;!AJ1zUe;t1mOHVsfs5heya0l&5f7XEdCrZ-ye?rO#i-CPc7cq^R zCxx1V4aE7*1BtKA_fsA*QNiN;Zl@iuXo~2FH^*aU^<013tH{QbkVRYQI0P2Sz|SVqM1;=$YusXls&y`??Y3yQqjz^_A0Hb4iahCwI77gbjhP(b zdsc5yEvA>(IH$YsS$TT;;E9rJy71X_vNPH#zOuf9m&X0!s*xdcMb=xU0BQgBz0|Yh z5Y$=GYhzqv%^g1R1JC>xC_Nm6Pdk6_+c>@x4%#AW_*LC$YFbc^Lj-MD zoff~mjOvcQBph91fow!mAQ!zBG;4c`oqyGY2WD%gU_o${}k_IkDp-KLAb zu+w2m(7$_5&vO1=tXEnkm|-cc4Iclp*=)UDxO1bd!uOaqRdj9>mv*@3^Hi>MHoAzr zuKRxDs}*j77fQc+b~hGbQ;iQ^$#5#3ZV#%}Bgtilkp=VpeO+c}+k`-arU9boA7k_a z3UPujBZAm_w3nVodEJLIi<2!Vl$fcEnMj64Nt5AB%r(yZd} zU}A`i&@oDgaW5TuVg{F~1S!tcrvf;el1kv$YvL@I9wwF=1VI#&xF+cfGMP8o=jVlV zWAn0^L}ubl^Z@2ksq z?%pZD-*sbGVCX(+KheZm@AuDyYPknA#-~y}2GWu46lmEeJ+zSEkqA6F`CmVBJ^K0> zd(X-@P`u@O96ZbEspqUJ->>aKvrV_bH$>T_p4|i)_#ShiN)-0<=3j6&wk~=Ymr8eS zN9l$jSeUb;1y;^Tsi`4sYqDBm7?MzolmiSh>~&igk*~Q$Z>(ER|3hx-7JQRewKr z8OybF16x!2(-17|on$#pXcd8~I-#{r%=`q_&>ny<{1e4KemM!f#ecYRBN%|+w$KfK zf@&{tIPxV18W3-uUzF69__o;sugU_pfVOOLRf=*XPL3Ozq_Gq|IunO<7M=)p`PgwV zAF+6K2>x7}xHQtoqd6Eam66dN31(+aZB4^M1z;Xb)+|wWJde%^hK5IQ7{8IJV|frx z*3i{$U0zo$KBV*_&Mjj-GbUe!Qn`8g;pEeY$dd>`S(MPn+x9=&X1RJWnWZ7KN4FVe#9 z<#46Md?=&Za0$LS&%OS!Fxwea$bV^J^E)Q!nPnh5bL1O3;qju)pV6gZG_(xaaB!!B zfx*$NhUzlSm&0cuM)?Gol zc|TfV@AiF&WaNbNjb%@Ec;uyKu$0z2?|w50B5KxxLpib7&{Xi5TFbm?P!}YKPM=aU z3A5F~4)w(SDUfX2_W-Lu#jXV7ESURROd3I}OjjyY@zaN&dw+7gs)QF=a`V6$GfCvn z{Z3z{7Ax$sjIz;|^G2-YFAydqLilb#MOK*(vLLS_${@E_rJobKYuhkEN9EzrI2X^{ z@gdPm)C10Jm;|V4c_>99Sz0YctDQh52zm@D2gah-mP%{PcI6B?kW<*VvZAWVbhvF` z{mm?louC^o_ZI&8MYfQ18Msw4zKl-%JPJkukX>2K;OJ`=wKmJtO zQU)kxSW4+yX8ry^h1HKDR4A0V2Cn6&p)t{keh@=oET(hXrfL*{6SzB=#c(+U3Cvau zE14V^SN*CU%u_h>idOyy)oMswQ4Ms9RrF<1KDVlmJ>D_uFN04V5NA_w<=!O9)>4kA z_Z)||{uI{Ve1D!k~O3~Ou9L_G4HpUCAHGIapy2>M8} zzQaExqv{H~9;r=90phlvBQzy0+!vly8&^HBa6KL$;2L`Ffvv4m%UcoIeI~;0S}*@UqyY30cVF4C&1yztpZa|groT< zl{Zl{WAB!Zj}OkPo%l&+GJY4BB~S;5Ul(?r%4!^+QQ^{?sXW=2@}(B$re0lMPh>i8 z?S&M>E;afN5t3d7=FaG3t9BDX?B7sIxiWma+5v{GHDRya*CR!DPU@yekKwjamw0`- zaiqo8_7k`y2jC2%u2py}lt<&khZiW%X56ZinOhm4NJh;>m+nz56ULw0AOw3#unXBD zM0ZW#$&P*I%|Q1Kk{-&;8NztlPM9VJ4i3>#Oz803;spzy+Fi<8Q*9qETl9{RAaI7 z2;l-fW@KCWpdTs^suI}^5i`bhL+#F*j5LuH*0t!eK6fjdYl+~UXe#oWrQ^Nb`kcDZ z)R-Sr&F&F1ApHmcj{yDF5%PIJousfHso`vk%sIy7HhBI?qf)9s5l2TK2O!v1&<~lX zO3h3T!6kmMxYMfhfvlp{gn6?873A={S@m+{Sf8UbBDh)#!*>8QbL5M16TMj{kAT$k z!6Ml8&kvI}y*H#xCbv?5a7cBEE=MLN3MaV;G#anlp7b{zBSJz#xXx^$h2D(gvArpKfV}?M5sq)XD0kCF{LOTi{o0 z)*xB$r1V>kd}M=8>8y-*%&IQVatyKfdlmv^K~;;s7lv4gaKD*1g@N z84gK`u`%B$gPA7Q;0OJI@<=u=uv*HohKl4QVU_<%Bz<_r7Y)c2&&?5NsEKi>DK}LA z>w7IT9LpvkQFmpC#3gR58CL3^B`1Ly!?do=IG$g)6d9$md@opFV0qhuRbfVq{i-b* zCcP#fVlwS-`Dw!oa<<*4gGIaX+1+V>7X9+99V_vX%1y%LSui6Efqz;wG!`?4%>P13 zyo~;GOYV?Py({srCBSrAUfAH`R^`EfGFevJh3QJH=0ScYiHr;@L}B5%Hbf$FbsdH{ zu=0)RnM-`^u1MfGOfm|%Uc}2Z^5No<>O{BOsAqs6)iQvbi<8I*R-Fwf{ z!v;5tjrsVb@CvrRVx}}zZ1oW$zu0Q|F#)pD$1mf>Bk>S9wc-6yrpC_SP{wz#_Je}9 zFyk|d>Eq>hz)^XP!%?NFAh~(AE`}z8V1ehbqR^W2K+L+T@i9&J5^og~*s%LU)fKO< zn(I4RAeDoo^3OzuR|!5L%ly8+(YV;<4VF(#a&W`79%UPMpNVf?Pl9YdNj@A@;TunXapI9=Z~D z5*g9Pj$L`xvI957D184hwLK=i6I=|OGdD+3lEvS!TulV|tWM6l4|E%6vL1NZ1l~bv&19dETH?-kbtR|41U27|byTsun&C+LCRm3v7MxEfbnR8En%k$|nh#6tHKSqc>^wM_ z6|_r2z)n{gW-m~27^Y|eH!MEs!X4I_zqHOG#zy}(NJu8*&&=I&z*Kx<=>6*@|7Tue zT}S$aF`g(w0h3>rifiJd`VKC`hcDTV7k>4+m!AcNoU!Q9EF|*RO})v_0wZB^Q1Q0) zX>>q2~x_i^#Y6n9= z8Q2TuBY&3(B4kc_2!h4Tj-la-jWcD`@;lWN^Z zPE;6p&~DIq;=DmroX6NGm(M_1`SH?_bJK0XY!A1Wa_6I9`!_Mv5$fBz4|EinB;&Ge za|bNDZeg|@dEpge?)IF)gloeyb)xSy{Lwwl$KF*Y*8=)e@WZ1xJ!S%Xd+$!k8AL~D z+r(_V!<(`JxyQ`m&Cc9r-z_{t5XurgJM9RxRDGzG{!eTR{M_cv{t<`=<^)2=v>yLn4rhxkJ0_V3u^!Mdbvo5CD->12=Wu>r6@HN zWya|hnssbgdjr{+bWEb8{ob;795N{6N#Kfio_skV>8gQK$9b_vzIdILH=V6bwBRRQ z-#t1rXBRzck8nBr>7bb+W3_9cOLJ;&dWtfkTHHS-n zUY=K{(1jJ!*<|W)u$rrQ_KJ+n(Zlzdg;3Xv`T|;39jSRQBYocZM5yXcej868)6&|S zrN@_C)EjmKb;T=k+gY%tltIDQ>KGx3yZ=@xwV0`I$lLc0mwI)&QX;q3M>Myy_uB2# zSJ0|{zOAuWOn#_qkkZ3USVLqfCobb|T1v{GpZ-k&652DwWRC*guBL|UweEveLLdWlP`9!9oZiM7+066ah|6G&%bV68O8v8~-8^Nq?A4#2VS&KA06qG67gvIABQHeOYa7Z*%(!n~ATyl_eXb>633;bePF8 z&wEfH{=x=K&=WrNIGd6D^;sE3j4zlKfVWH4NFTq63*3` z|EVf2#;fm6U$4qHoC7wlC3LV`$QO4;o1k#?$>pT{}r$`eX_b9x-*WPb>=$UX-D!0 zoym}R3(;I8s+dW)G`3@^TPSk??4s;_Kvt!!!ETjG1h{O$wxsmXdd{S#+j^@J%Bo!d zT$5K7r3yZn%GaUJ7oJe+$BpxVxEB36-Y5`uCm!_D)O(E8yo5GD^6Hnx{Iv$GMem_G zt75he$-Cvrx>-$~4Tzg6<7=DIGSfvObZG4(PibyP5W0SDv6A`~XMfm7!H6nZQY}0y zDCv=k`_?Wp^)96nEN#g!Yi2^6^Xom&Dxsn|fI-?^KAppUrnu#q0a2L|lp@toOL|@x zCA?PLl(V9SO%o0W&JYD-(Kb-*n2_M`%W=&KzU!FGWm74{$ZQeWqF>o;m4TA-%&r9k z>WX48TEUSvKNCmiIuwaRU5|YfE5Y-xC6VJBq09hZGh5#6M2wMw`QkIojA2k<9L2OMADSs6DlrY&i=bv-{=Ui#h0*>Wif#uZy?T1W^*X&A_@iO9D zNy0dx<@3Y1(g(lNe09DrBH;JKd`b?ym;~>CCi`iS)hHKpBQI>WaH>$hwHtSs6Z}wW9HEyuEy@(i}+LsapxE>Z(+5D zKgQiwB(vPXMk}_5%H$_mN~CP!FuFAyzt_WkR~Mq_-6`a85&0yKKl(db1PrMUaGKwJ zp*i4eBI?e-Rsf)@7BRB_i~ElC|LVSDVq;?e|L!{`CT0f4|Ni}t-IZR()Xv<+f{=-s zot^W4;1Z%+KwYw;u<3AF<&3S3SXyj1<;YsDODxy&Bp2K2uUX7+Hd}1B&UZeu+;Rc> zmpjSLWRG25dcL~~aTMhXu$i1`K%}@=y65RwX&yiY4^&e!KxAZU5M*Q+9xyPh)au%M z{6-!y@Oh0<$w9oc1P}!?0>=SuTFBg>e6|5;qyyt7w6eA4Rb;`m}>h=_;~#@xRkAkATcvAO)ik}F9C zz|TNj+#oZ6ebM0*7+OGobg@8rzy+okCXVgfD}vf9!|IulfKb-7(m}3u1@P@&%mmDV z!g2GcXd(Z_ENlR5X+vMNI+g$dPIMJxeGVIk22jaLJZ)wC$twj%j z>7TMPjqU>UfRM*r2hdlR-P;wXMr3JpYW&o%ZmMKFLkhm8wE=93QU8Lbmd{I1NUkhD z-ram?)%jjcUe{U&O~%!!^5st1VX}N1+M|~P338`fO`Ej4*`imctfhk!2+q|5cF;JWBsg(aIOJI5A=%o z{YC&P9J3#SHbDE1X#P2R^*!_v(NC%2W=|yJtSA1YM0%nl<7OMghJKu#GB7emR zcsug@jg&iJ4|bsZMSt*b==WQU5F+{CV%`T%Juv37?{9_Xi(ce#-9vVedg~uCLcVJN zv0dEE8#{=p*#k~M1*;<)TQhLr4#7!H?{O6%8Q=p7Q1ute{P|TM6qwGn7I*?6fX3OR zkI3G(AJC8Lw|IdBQv~r72TBJ1`UT1iO93`FGqpDSfQUswF!%9AdH9AtIu7sR(kmR~ zW%+{>2sZ`rx9QDWCSVkNV>dDX2H*BGANi8L81IlIen2fI=%6lu_-v?+HULo z?14#U`Q9Q^fReLAs^_IgT=!aNuKQB|m_Kv;%ztg>d=i}Z#-#hje8w6w26+LvvE1Sk zVdrKpb~`73CLzv#M#t6!1$6{!8+Hu^IKRk%yOA+A^}OyVa9@Uad8<^>|V ze`<~^<0)KSDXe`<6>`se)++u+PT9iRJ2&?^#qHss%L&nct1l=hy%onH6L%+oLoPK5NC|+ z&J8P)hMc{oRq7uBkH?FI*V-%USJ;4AOR_r^hY4~{B>7q4a^X`TOvyhU=t8NZM857h zw4vqv3{QM%jXl{slem6_>A_C_C!T2I$@^JV{m_=YH+^bFeVfZ(!r{dpl8{~@e2nr( z_!a56!R!ax3GMT=C)@oovN`cQDgAsQ!&QBennt&BF5incuq*K~CvG)5b_l^(FN#70V3Kuk7YY_r^C z5dX)S{a`}oEd-9QjoXJM2Gk1-iiQWnVx;zk7!B=15eiu^r5j%8*&LXZao!wlo8O6- zm+@E5Ecu(x5pb;M@6-s%f6OoTH>7@O@0455XnoD?bfL`+w2P{0$PC{xYpAe+N=fgB zbxpb&(#kePElgLp3Xjv#t7Hu-(;X{=Z50W|!*wkzj3ABpU-dd)5T9F~{GRxkO(w4| zHtz<(dUdJKyzU5t5n}0HljJYBrU})B5+D2B9eKd}K9L?4+c`5NV$X*stcM z`1`~`jF(nf`RfFmDj>|vo608u!V6y zeu2w_>8oDf;H1A|YrI|!-I0yY-pe`>Y%+C&wB(2Z(R-`F6xrgEj$fJWtxl@?Ui=pT zK|sF0sE8Nyh{hFl58>Jcf~wT1KH%!nzz~!O8O(Q9CJcd*BPl>`5mnlXT;4m3*O`P2 z>kaR8p$FpFM*eaaz3LT=Yrgj-{CXYQ;N+`fg5l~1aAP}99G^2MJSDT0?fXmczeeD0 zSyfQXBxaDzj>F5bfMHkZW_(4x+RO`}A&D}7uN4eyx`!GG3%1EOO@%Q~9h-Eng093W zo=p-;&r^j;g}U}KCj3?gxq{)%d{4Eg%m|o_YcUvQw+|=uCypw3vLKDI?y-);=^3eM z{DjL$#-bl@C1x!=NF~@4V?EAQ!^wRsUV|Kz`9^j}k`WNbjr{BR(utUvihN;HUin(~ z?M`bO?&s201})E4vO-tO_5)$->MAQ!1qX4B1TQ(04zUmnhqB)2er~(u@>JquW1c3w z>MK^Qlxtb__@v*B7Y@&eas^P74^S8>=nu;gPz8%v@Jf>B`k_&m6d-+UlrqZEUcOQ;boWvQu zyKVr4bEebaS5j77{#(ezbhQa>S%xK9oP$A{PC9JKAF@8i;i5Vsk{RFOi3q(GsozG( zQiXN1C^AiIB$snYE0L4iKJGu1Hqs|xujzK+98Lj;2P5zL@nCUfhh`~RC@d09D!f13 z$_(MA(78GI%a^kB;CQdN#iwL_nBt)Q+CrO;)Z2wrGXBclK2o?U*pnlhh-FHH^KC-EMa6N#MJ zMENGZ!=e8cvj$_-fC#@()z!l>2~&KhcD94}J^Atd*lm9xMNe7#_#mdo`pPB&x5O<**??oPM;PN5{ulFdV;Axxtx zBFDJHSB!PSj$SO9A)K>%n{LZn?(?$)ftsv&PV0@m1av$pY$Vthuuv`^l{tra)Xp9? zZ0apT%`*rS;ghC`Bztw9mvtfSN?)73N24SHpyAMLi|@86FcIK0zkU2I7E1uMDc@pfY7vtUV14-ns17;qb|~NNDAX42l_RR&=dgTqQF^AxGU|?=3R<_4wC>NF~-D zWF_v@vP~Yp#Ix6|V%h}E4nIVwN@W$1TK|L#WMu^D!RvhB4Al4Qs zFUiSGE-h#ELYW{uXMw+NZ_D8Y{y_#VRzk7vf=?E1`%q~(S20Fd80Uw3SVF+cgzY!V z-MTyN?b%wY`4KS9g|Y1r%8qYLL9&1sT+FYGR&ZAH6K-%O8F*cy@Lc^p-ojFO)0wQ` z@LmiTx>=r08_TZD!fs{7>4=WPqYS!iIjVCkCLW3JOaZP%xhD!hJRC~`v7zc^gkI7V z5+eVt65e;5j(WKsp15e*8RAqSYgxCEol4B(<^GD~=lo=oi} zuL3My?Bb&9JT<(o>lRSQ(@FKoy!~;K3mn}qI+4-|!{SnI=6VYmoJF`ll4II8YKxYM zGC%aV7Mlr?-4=3zjoB!Cn2MCG1kak}&FMIpO0W%*c%X(xn2S=ljK~M)U0csHdnxUD zJO+<1LwQ=IZH?gT%g_G2*^3^EUJU8dk%WB;4w+V{a83QXmM5s5qp zrSCl(M7wZ*0H-qAEF(fXa$eB9=TS(^I~s7AyzWnI zAQpl)4?#>bAkbb1=sg1kz>S$^qf|nIm22yws-w?dx9jV{Ip(Uu)GI0b*X{?VR=prH3o{5eaa0@oz_$FHvWcvLPMQ z$Wl>M)pY{kI?6&L$kOv`t`s?2uSsbgx`i~HJ(O)vS(YRA>4;Uh``T1fi^g5`YTf5l zTFwDet0|23hW4K!W#qE45MZg3gy5@pvwn_!g)gg9AoP)ys9Rk;Gq6cDS?RJr@W(nf zlB>wkhg~$zRnG=*>h*aFM|0mem0MkE-ucFsaK-$EJOJIZj&NFQudSO(1io%*9wq8%n|dxSL;$M+U4N?**# z>BseMDn_PKDdqSa+o8}Jk!{fteVhDKYq|Cw7zTTi>ff1<^m}_1x`z<28&->Wm;d;X z8Fs}Y=swj73k`8_*?K+up<4^wIERD_cRJS&K56j-j)liO2@E{!9p|T5%m_-S4Ezf%5-mC1$4_dxP}uXU3wdXc!*WVx%D|PD8nD@yvk{;>To062luVJ zZZr!c<$6>^3DTFQ{?@B<1T8Le~Q zul3GnllZL|C7v9LQECzd4is>>}jO6Qif!UYUWGt6rfoD0p_W0p84 zp%`8r*)Iik!6LOOK5e=RE4-nXL$XhbOcs1&xPoP1_Bfic*1FJ8VH`<7(a_qQJ zR^-FV83(YZzH^DVBCZi$AaT#OUD+`%46o!{z$8saSbh3^UET#_G%t)QE)}9d(>2eQ zE0j!?wa@{EXGu+nI5m^x58jbx%td7o1#rn3wb-VDA^PWbk7TW&$FwsNA( z30ge>_F=qac&E789;b=CAi=H3F>hv3)ps2PIZDjk{zSk*2vwG01lAInB>9COp`UH3 z&nN51VTqc7gUZ{Cc8&_{vYgZV$$V9+WN-OrW=^ zQB};^dud!IOycF$y2*1s`3@t)lqARV>`hXz$*BCx%*S;`b3fMAq}0Qo`Td)ul0`|V zWxG`7@-E{rQ^Z=D>d$^pH+2n-+C6pA1_*&uvlQ0D{UlOtr;&!1lh>snqr3$S3g|w0OmrQ~nW0<2?g}pgGG!MH@(?^oEnvO~<{@7O!N{7Igd^{3Mx@b5Z~-m24;fw#G4(d=09NL^&LDZcMnq%JoE zDhBNnN@%pbIE_JL36#3+t@Y4L@`SIS_jre7yib+V(W8h}KX#w%03$*g^WHSTS^Fsx z?L`r&ptjLi&&rQeu64L3*lLF%6Mu(AKgk+;OK7z@D@P+R&J$%UCUeD7vINEk0#Kxol*7)#jbC7Vxt$# zh+tImAeR9N!mg-@hxEmt=rCwDnvIKd2b(Q7M!9vT3fx{{Rd;c?W#e%}QG3*6i;T6% zw>&Hc6Y3R1bT=S8Bk`U3Lvp;Jq^Xl$Tdh&pfVGjh7yGn(6*#@v2UXB#jN?7;5_H*&iZg23~IDm@~`oLLIrtNq$%u)u+T z!kFPT{%B-;mW`G_fE1xyF%p4dG|@IBo{`h#f!F!w$e0KpG245`>O#&q6dTRY`bXvN zpwMGZ#I|2=fG6_Ksb>8fn3Qe%4=yoZnCxla`n;{M71Sy6zKs0*11(aZahL0u*pXgt zoN^%N5%N^lNC03|TS(Dml=SUnxqZ;3Sg_gsXG@=f-qT0gc+8n+1rYL3~%T6W-p`0*khQ#($lpkiAXL z;a;tZr>2eik!%sCTrT;QZKU92S1=W9l5bbMf=AQhVkbpG}pQfeJmV9ft!0YU{ z!B_uv;M%cscAwgS@W38|InFc0mz?-SB|qLb5u}r?vNw}t zBXMe34R0lGAM|$do^K7N5+DijAQ5;|;5vK{Q~+XnJ;6v)Zc`ku%DvBHU#QZRSqDsb zJ;@qlh*>X*Rfl+rtxZsm7bzNDW#V8M1%6~JzMiBJI%}*1b>VvIS2jVn3eaqvW_H%; z2im6JL$W)xq3G^rk4f;N&?!(BQlVQFMd(#2D0fO z-}#{1mPDF4R1*aqlac)R$%5BAIHk(;hnMUTki z2{bRBwrefu5@tP(ojFrQVCmt9Dhc#=ueTdKh#DkHeSGCf+r34FRo_J#iG z+Gfo>-j^!8>--XdS>7>T{(?Is?e;p9{xRFVY2Bv?`Lcyopw6o#A18HfnPPDl{bW|CT z(@(b0?_-wl=rJBj2xj$QbwKO@%k7*ntnOp){nL*_RsWJ-$#C-+E9hgL8lY8K%~3f| zK}EM9;#Sci_gPbsqnN?0Z@mmph-7y*c~95?uN-?<7NLAew1Jnxb!lkkeGB889o2V@ znw?0xjp*3`q(elT5h)QelSw9cVt>hd1aaP&VxoZ*D23z+iB`;xt1UB!yL-!Cu{ker z(FQ42W&4e7_@Tfpx}mq0x>%x=NO1MNnP66#zArDA!2Md+)sT;5Z1j<2<>Bi@72zAj zGa}K3CuuS*2|=QJgh^541X9+g-_B0zriaFFkS7PuFRAxgwv}tfTZmr4DWg5{imz zT?Bh8({Sz8CM5gKo}I2eJ&SV5dkP>s)SQWQdvhOMG`zJeBI0=F5-o7pWWY^^_z~%| z+Gu+FP*NSHp4*q1SyYU1<8_uEd{uQ`hz4-Kevi?P8haP-$MjM4|oHTDsOANc`5t*_uq{l8#=X63^Y|Wd#R4lW%ov!Ka9lM_R zYw#oeXr)}jkIi|(*r;aJNPWee(T0fJbQj;@Hr?m+Tzv%nvOV4Pibq*RtQGLf=xG3c zkNVzIwo5s)WPkQh2mH?F)4Y3p|2_v#dwenr^#JPdcCH}uyHySc?M$|XXuHO%H5aq- zG;)_@*`RJ^9L}mTsyZM<>tS|7lM3IzhEtGpNmj81kOlAv8Lr?6-*z)|vCa2T#hQN? zB$C+rLu%B`WO^p8CHDf$Xst*mlrT3kb{IDSm`LoQ7*z#%5vGL%`9PUpYU}@r^&t6{ z5My$xG1@#IPqHfSW1`IlMrn9E#!s;>ly)%;0%sbc7A!2k-LLhBBoB7FNI#0h9StB3 z)=5Kv=wE5YM+LXFW{ zjo`-CqmML#ZzSOOY%gyEETrmr5$#mjQ%ETuqzs2dZM8#cNhga&Nxf9!>%v5eX4CES zK0MPVVia0;BhJR{2t?789vVCTl=H>(LK^Bl;SgAJ(<3FXpw<*=UB0*wE}`_DH!eVs zpLoYr&+v_LqS4vr+N^Yw=2)l1m-f+6@YP(GS91#~`Vu|I=Ys*Q4wx+~kE++YhY!?p z`}S+(wJw*R%%N)En8!!B|JKGiXlB1>^h6jw>+Um0V#TRyqR5@wLf|nnixI`za8U#ASnnRp>%$Wx%d$Qxgb2h>`r24U83SLC{ zc4Y`nEkuqnxd1|NXA8F#Q#=9F>wg<7_sWIlqn*GO#Od>cVK7;S1w}Z^qM-L+i_m^lPCc zP*Fnx??9fRYZc3cmdxkpSWI3iF5qhO^P#uZ(z^An*P@xIAw^s|Yn;_Md@8+r}U^QDc>3fly1-{yUeGPV2U5E0F;3H?OFGv$4&lAZU| zK6{<;^@19in4KvU%=76pRHaOfM7q*yfifc}&Npp@@v*tj*?#StNGE1_gfvoFQ#zxi zqT)X6ORitMQv>1rw(5zEaU!5srw{BlELN+6DhO0w1BnXiksC6D&{yW#?Mq_uRoc)L zE3Ud5XC>$jRO~(YfPw-?tjDWf9lVT}lnltAtHLwG%RCA54|=dzoQ<)K13G*j!a#Df3|$HW9U333=?w-L5oNDF|5YF{3=z7qFhrFI$T6vdCi!%tdV2WdNt%QrB;6nb zx?p?f(?&EsH?CuCBNG#Va!u0&=Ex5}*@D!~JlbGVAfM#EwI3h1QrSP7iYsxDzkrE9 zB~g65`ZZn_~h6&GbUdfjJ(hRA%j!JjfhQpZ)kfUA@Wv8`I0)&U;I8e z!ewrpOnuf4JQ#)6anr}?(bz*UtMBDS45cQfdMzJ-MUKAz2h2O+k2o;68EQ;u$ z0`HZml!{+2wPB7;@{pPa!`f`Hjz=!Og^Hk2-CauEGjr>{H!erB?D?mO`;{BSQB>#g zo#++>QBkU+&9;_HC>Z)ytp!Jt-*c=jY5XO?~{vl3cl1>o2G3ESaCM-ZaS^q zwA>3hSTdVY)AWWnr?*iioY9Ofo!5#j4-O|1ZcGPB6G2U#3(R|S8#xGdE6uAYgc@khIJex&U~6d@xe6RYVO#P~tS)6r7) zi9L|bhm||+6w~I&lR?bd{7U-S?pS!OOxOzf1gTZg6oLwlmyEN!^@SwrV+#-(YIwSQ z`~c0y=HXN4fU*dLT1^F;1oKG18JD%Hk@IS_b@ovPKA-j{H>Paq-g!-0K(oxiCnL^D z<*CAtu-~U*l$|Rakw_( zQOFYw9-aKBC8ubxm`R9Tv6K5%&iTY|Ywn@XZKeE4M%SavbO6m~2E8;-Wq7?QW0@4|Hhmsi)rbUY1zP9Zs3q)_g(N6Zo!Z=U|Jx_xb$3+2Qi%_FzQvl8*L|7%?ajX z_wFRb)^_B+D1(Yg_(b-7jpdS`h=Nu+GSQ)f)s`8{@VWR;_=N6}x;z}6NB2F1A2H|O zJ4@B0>*1>vmWK4nbC}5WI*l4!-eEN7i$VdOxxIA|*#w&oUmgYP&EJ=v6Z!^hT9s@- ze7NoC{<#>?C72wDy*g=kN+0lHZ{uhDEVsohc%dBYEA%=pgZWR$b7~6MjCjOcNcsM{ zWNdr5g&eU@>D|_uvRKT9jB9!PVVN?wPx!jRF+Y$`JGr{F>rGJT>!xv>zy~G}sC5e_Pvsdh(5cjPxI_zs3$>jqY<7|rMslF=2zm1P)J+yu zBGQorGVoaR!I9^uS0F-d-fYVT+BPpssi}ILaRwlsrcF*|Q@jL>B}2VkWBx>Xp%1uZ zzpbR%7gXfskPaTpWf7iv&xF*E0_kYm-R#4po5+du)U5=eJgP=XKkRWeYGnbBotlowMnHtsG&*@ZbT3?E&T8)$~ewZxCEn}1qYhn z(`v&?T%z`olA#gn)6`uR&-Ve!E#oiNA#Zo6-j!J@hi2q50uxnSV^SzdF`Sl~p;)o0 z7nEfWGUn@w4J2CO#O;n?_FZl-*y@7>%W+vh$Tqd-D+t!?hzfCM#&t0GBU&)6yP9Pn z-~&3z&JRkv|Be#LXub%Yz z{@yjc!&Z|h@kae)0`6Fbf3*9{0Yas&HL=rUF@=tYW3MWl=R~BQC3#N~y|F`5qteW) zF@|DZ;KuUo?4Zw1tHqkiDWV*1v0M$r*+)>jA>nv0)> zEvBQ3Z6=Ne)uD?kgO=RfzQt)|IOWT<^U2u`28*>|05%xR?syy+eRmUaJbloRe2i&1(dzud)UNFH7 z?x#kJ!Ia+a910J$PrE;1mQdFvng7J+u7N`c+dUN(79mJ`;;HV=-#Kuz;6vae$UyDtsb4#qm%i zczzVpe26YXJ^*g-CPS8|*R4H|EcRUryJFdrFgno3?6` z8g8cFkx!uZ_UD;%rE5Z|bgyJ%-l)p_dwTNH$fwaNcFcAq+?fvo%6;s6Rvb-g?6nVq zj@LDW*$r@n(Y9fpOSwT}Jbp`ZxfcxURlOINDMT@sEYLlm--0^XzTqh}_`Yt*RuWhD zWS(g!;>i&Hw^~_fn4Z;ou9lu!?Wg!c*)SLAVPaIkv9a3Q37j%#jZVwng#5F&p$A=o zZ)k|*-6PQ;P)ByAhm|8A6odAYo1R?6Sbz0?sfQMLD{fXooDn1!sz{_#PghavS5N2jFgpbI5V>i`|IUt zE36KrarO0u%hCt-J^^2>hu#y7&-n3bC1<_G1wpDj4QMb``+AS+Jz^~$U0D3WP+rl) zF(d42#Rws~YWO(;+HXc8Qlic0@7#{Cb0B6e+iuu{5*+=^8ywy?<=bF#bsmCTKNF zJr@i44#KSN=rMbL25PLB^r@SoR2`ETI~egh_inyzpw`I!v>Ti^8_!ld?tSZgY7@|x zz%4EEP%^BIqwpY1a_7AlyZx8xsPPG~TNqJ8gtAl$W9Bw!#&vO5ld@`7JBNEw#toOy zkoEieTvN55<2~DBTBZU4Q15;=yXvz86HWGMo_k7t17s%I^kIJ7q}2?tiQ~WX5Q$CP z8IYI=4c@?ECy5i)X@zld+Y|KJP{@5`Oic$|$5LTfGN#9DNvH*yoSKtm_G9sWcDg%f z!fCIJJ)Quf1Z=`K&J7f^i>kA3=uuZ*%wi?^zHHP?IB8sRe|n9s*EUE&fhS-J+2}b6_3@CTqY$1;`^j^`0dPJfrIHN;4?`TKF;2k$fN86wB*9{Yd_BI`}zgdF3rpvic3LM1k_1 zdAy2k3$!xp1#@j(hGn(_vGkI+Ad9w$(obj)W@8eUW*!6qoj2;PLe!=0$XK0^=wOW{ z->ial#8dA4)n=_e+S1t*t<{!$PkTdKP>^w?9a4V2;AaPNERcb(cRYn^>yw-0LvlW$pbsCecU4ayR>h@1Z7Ru|Fp)^YUy2L-cg@_|g_V z^}Jnu^|WX|w%fau;FCyS&L2#4BcA6vYiV^Kf0~(wIEH1t9ly^c?Cw&C&>nmi5(th% zU(~ZEtKn2htYFPa8Nng(Wz%y0^zqUMRth7osvPY78~?+a(FU}_&08XW+{oR!dk0z* zmLFV21;yLnjx=EQv84(D7y3IlES&aP)8G$l!wu3%2iW?d*vn|z2;{@dKcgFMgnKoP zNGA3Nf(aA#%V%}h-(tKK{hs=fbgwKH9?}g1nz*cLjYyAm;$suaIrTsz@ueiTI%^h% zP<|&A(9fBYPo^L9ffjWPVhW*tn14j0={|LFSNZ+@ zyy-bgLmVaJ=Z(eayAiMYitiY%vV1pc#n=(|ke!jOWEdTTI2$Jj(-WE#4iu$$V){*s z@Zo+LY7_GJX*W0Pl&L*(vE+6iKC?Sm>zkVjB0Nm;>@mK;#I^?COj|9)0^r*^od2aF(DsD#j58z84W;s6HmIVF9Vnz zhhGF%sfNRQVu+J?Jwn(Bqigme5=3vV#XHaKY-Uz;nk91}Ivx?Iz~frI3|Kc#+6_w* z5pGGr9=wg<6Tq_^Pgp(>PQUkQfOkkHXy!%EKn^f0PH+r4p_c6DxM_Zz5R7oU z8JCb*rF4JSm0Uq}!;Q3Z7OY-g=?d?<1Am-I$z-MTPXWM!j z&6PN(IzgR-Bwz(n0C7tGX?-s?D#_?9q`6nf4ChGw5zfBWy3wAuCRlqzx3x-NWPVzm zx%vUa5qzE=)9b{h(o4sciFM0me6J+*e*VY9?u;DqVMB%qfiI%&6B=}d6n0@JDOy;* zxU|Qr_f#acKXZ3Ak`04;{WJuFa^H%LATw(^*XXHX2wr?~5b|<@*YzIT|E`bSdXhgU zNZIaN_&zH$1>qjN@Y%>m`mN~nUg)Y5$4-9@k6>cbI}SA&fpsPi>i%5I)u!Rk<|df| z*`_JkX7Lx*qJFS4$-U7l*x;q?tg1t&9;qf^&@Fv(KfG@oRyl3OuidPDo#CPeyA$HF z=u#rsSeD*NSBp%^xl4?CFiT%pJPIl+Oyq2_kWd1je22xqgzRV|cyd!=Mg$&NX(4^y zI#;!cUHV*i4GSk!8J;vy3Z@%%&C4gz^_s6!?+M;Z74@ploqE3~xW>~AAkhU@4u?vs)Nr4RV`(nrG zw8ch@jlU@z2DhqDpVfKpxI{ea>EH@mb3&0(ZTLH?NQBOHGum2&FNkdvn6sOG)GYe2 zXPSF1iS)z%lUL4_+;V(z*OqtCBDU5*E)}*K8!wBUG0$z_L=3~mdXG3&RTx9cvU(!d z0Q- zF!T=`8{d#8*7Z1U1FwUhSzaJ4&w&gax zfLxTT&HW;xbCW)fG3KLZbl;zzINP0f+2dgh+xu0Bt#YP^%$SF&*-cCiLxQ+{clp+Cxtih+NB8Bq1HIuxBYs4?8>)LoJ}1^d=l&K49RG?#YO%l=_*?z)k%< z@EKwe3<2y>-ROjZkMpY(+eyr>!OtdAkx3Tk(=WlJ{&JiGQer{6D#@0l(cKrFNH;VJ3D+v3zK+kB=0*lq30H*29Vj~(b?CL94cVgm_pCcX}a$@(=58$;O+`O9n>}U)-M%vtN2i`=a z#f4`)`&`qcvHPYeHzKv=7mg43~;dbPd zO|+php!-%-+~h&tVgyg!j#Lpd47t7aXOZzbOsFhbrLX?R595-}e*Q*(2?n!XJpUH; zfNNwVAz|iC=WgL>$dvnZVU0b8`Rs5p)lJHb?%1Se#+!}Y$-%l2f(Q*HkJX{x^ z+X`njF>!MIcl`Z(GNG;Yj>gsS$SD-rgz4I1VJHO#`Q&wDF(xl7Hu17B6MBc4u-kK% zM}^dOJYI2dhckk;jAL1N0bh59tlinwM(=|mBuEJ8z?-e3%lK1~7P7Yj2uUrYNXv>B z7C2?#boz0@NrjX!c@g{Y+*e|Jv#Kk5r#``x-yTf89h8?;{K_X9tuP$aaEuB^UI(M; zcs^d87%Uky%-WQac$MOi9W*E_!fPOqJN{NVd^s^rd>uh~mIym^&IUbK?BM;h;AG#< zbB(6~ycj=~sBLXg2Kp7*4!UL1s>nBzFZA4qO-9_EtD-em4Vf2GlqM1J`!z|@QO#n39BiiLxP6- z;F$3Ix#!R|aLDZ^QpXUhehHIFCH_?Yx0U->?``CHJ@vJ3^F%T4sWf5;U}LGiYKLAB zcI#V(cp7U+?P@T6+qNLtnMY*mV?aLAhr}P!Oy4T?`iOlduWq%Ck`C#x^nU^v8|UO- zLJ8G^4U{-|njW!><)okSH$7VuiD5u*u`T8ty(`P`55}yh-MPK@66|v_;r4b!;v_Wk zar2>AibO4>-)9elqar($8s$VD!g5VDc@!Wuv=43fF_v4E6L;28p?p1Z{U$tONR|m0 zBRmvXUC*meQuj~eydnr1iJyiR20gusay!bd<#NaWbztY0<28vM1d&w zOruWqz}kju{{r;m3jfPQD8oXls+Jq>E}oW3Of*!b9)OWI;dK)njKqicO0Uc^2(L^J zi&I2k4vTJb0?Za@PlnCOh2Hn{M0xk6)C3^U`e3gV);<4&19odrUA8o=$Xz%8fyjfQ z$~T|Aw24CJR%V9;r_#iL|9Zf145hB&W0XT(r`;Rg!)OW^1D)1TgM_(6fNOp$FN+oh z>PX!DPgNyb&R^>b8(}8pz>0galQofBx!yUQ1kn-aYjwGiHWY0rV1IbkMqs)$;C>`y zoC-4cNpsw&OCTKe@E}!_ACMq0k$DKGk4(D0Rcs@@x+V~Gt}E5e#=*ALiblo3fl6-F z%()GOLg571rnBKOux<{8veJMTRB}@8<-UmS9M~xbe+BB1fHU}y(bGBRj3vq!9L|9lwu$_fmI?2WUjP dwz552Xii|-IlwH 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%0A9X<%m*?i^$bC zagPQ?W_#Sxe=RKKN@Oo9XGQyMjZ2UBKjDq(Ap*)sevP@D7YKa@9s0);bADr;t|(@f zw{#cpx@dErK8?c@=Ei`FTHi+ZmmV1-&jDMb_>CPX#Ax9)!j5K2a*O_2HUZn~4(?Ic z>jy4b=T9Rl!7H{8DKZ7pHQ8iCsHF?bF?8FMgEGxde}_k?as?gg-zMVLH&bkrm7S{S+znf41aK7Ad< zN85oLm}lRA3HQmt8)zOi3P<^u3=RaI^qxw2VRJ$!VOuC6(J$GI~6%lpH zcTiHxDFyeui@J?`{CX8IyeB~c$Y!R$ijCoC9)9dSsX|*(Z@yJAk6^>#_)!#)DtMX> z4R?pi1F?_UL?UIA_fv^5JA8CRm4c4nlIM3hSY`M8%OK^JH)faXSrLCdbGrbjZOvpi zplk?oeYhbeCuco+tM9{e#Opm(&e8y7rMQ;EYyo|Pbv>c_Bl`w`zL8qJQPB0O`M!NsHzZouAK5j$3fZ(We62+pN1Eexlcf{_VWE91$7L-jyT=Ss6iCR{f%=u#UT z*467-HH{to>DI^a%VuJ4&{Pu_ca;mhQX$~KX5WL4H>{ZW+34$X8Ef=2#CFx)(G7P&{=N!hdouuC&* zGzgyz%WEX->29#4A9>@H>zw=-bPA4lD$v%Tn&4kvjw(?HEDcVfk8atE)4njjef<&rFz>4BD~R%xO)Vnv z(0M&)!`>r-JNXfnAJA7p7SmV7!c9bOY*3$`y?}7RfW~Eta_{n!$e&6?W$Clg55}Y4 zgUmsee%sArCTS_#0Aan;oiNmx-o;J7p%Q!xE= z^$5z*hDRKw>-uVLuwW^`mg?*V`fA(Ujq%FTv4Wmk&6TfyX12WEbZN~-$8BzO5!t!! zpbRAliK=rAmL`9eq$j#OldY+MiSMR#G%zGvq-6kq!T$xwGI&3f<|zY#tfR#Kk)=WW z5_ZOeCSP`R?9~)@k49huZwbBr;iio)e1)2o_sRiib-SWbc(}a#V zMudlhYDrFOb1}$Z?3%GWA1X4;ndd{RQQ&`iB{xki6|Mc|hN?!}I5=kZ(J{ERn~4G7 z%`3x5*qX=dQ)c5j?VR7o&=JhW)emH15!uk>W~rGm*kA&eG*MfFHU$*^guy!!WK8

UXI=!u7^drx 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

9RT#VV)`zi zl-t+qk=C0|wkY1twK+oFiMCLCx^Hfu^mnv`&7Z50{KHa2G5!8QF?{z-is+V+Z$@5_ zTU$+8e?U1$57272Ohyt549{{w4R8DONAAXPSLApYlq}-CeX#_Bfo0$RBKH@fEMGOU zuOhmn`<>UFPdk_XR($w}nP~USv5hN8ec5z(|FKbzb7T0u|LUGmBi;xC62*0s%|Nh^ zhwnkQ)K3f#hg9!QoG9Zq7o6^lAe=6*hD&p6pNZM!yDJ1kF*$TM;H18oM3?cd+|_8{ zj%Dy~-@aAaxzq5<-MDGy;0v(H9>gXu=`V~;&cB8BtF*sDpi@_2j@B)_)@YLj>37)E z3t44~?ZvqbB7&_UyQ=|pj>4XMepL2C0`^qWDSfHC@po6Dd39_8&u?E_w5rvRQ(Aya zR+w<#tdz4rPjmhl#OM>_+Nf2gC5ds^NQf5369pYD@Sj|@6V=wA9ckY)aC7gnKkjQ7 z&HdT_>~S&@Ojh-UMp?XsCG#MVt>jsQIC&9ppKT z{PeFM=%E4nMFma<&qKenII3cL)SzN&R5tO^d`NKVls+l}E}nE@(Go*kE1Dgxip$Nd zXvnHKhSB=NcR-Y!Ut>i27QjzX#S^}mg67uo=^-Y3c!(_%BJE4nMG-5M4XmuJYs(A4ELki5#Sb!2k=qi|LBZrC|Mafd&4l(?+p=kv>CbK&v5GHOF?K?LWlH zhnIhl6~y}Q)!0Mp`4Am`SLjM06yz`4ZROnqN&O8$7t#23fM_cg>mq+w4an`PF_t~Q z0#xFoX^JUH(7jrI2Jb69Behe&frx2UIcZ4WqA^uJTKP_04dVSgy;&^Q+1cN1G-DC` za~$6-nIRoOu|!pivI>5PH5YjL!Wsn<5=iZb=sUX_SQa1_Kf=}5idVu1Z!fe{58D^C zQXe%s`NtOGlCk2AT@1SLn(xuvNd`HbGL`Y{u{2@7rv5Cx5S6x)R30Kue)`7}A=EhZ z;iHj#=5J4gqla9Sne2X+88RGTcypX820xr+Wk&3~kBTin^S^}4|B#vZ_gCZzb{u|7 zVM4BT%s0SHF*DV@RGAUiKWzk&gy@GE@Z0Y9@nUv!1En&1<^z3%HHZ!8nkdo}nWypj z3hC`gu@6*Ow|GkKzm=fVRRfyhK$x_>BFr~#-l6OMhH$kfjF#A8D$|~Sh%i@eo5bRV zT-N*^HFK5HZl-W@fnKx(a5LYW62Gi_*qciHu@dmKku^Civ;_RymHWdyU{{lu5eqY% zK%GXkI8*$2K~YxOcMv-KFm%SK%1h>m12_a_u6M?)oAWID;1oxUj*@as1@ApI1`C8XueQrX-p|v zU4dj7TNftFKvLb^P}H@;b3zH6I>J;Ympx5{|45oitt`ja|l+yGY z2R|wYQ;?){JL&y<7qNBgWM4drm}aI_8-Hc~4AdB{LeUGGaBfG>-p&Jpb4mfj$tE^* zRe1UhZ#ULe+RkWF{B!QcRY8^R<{h3TJdfqb^RQn&A}%NC*z*-|GQxlH^wKM9g3_*1 zR9i{!LA7yF@T!dufk*euItuPg>@MHL8?X2hgj|=0SK%r=v^BemNhJUL*nu+{gttOm z%cc713zGtUhym+@Am)@sVt(reJx(ffBKO6XOHyb^ITP@qXpV49XhZf|0acUud_zX| zU(&v$KCEzrb2lxBry}W2*}X8CPBh~q=d$-_kT5pB89*Eu9zq`Gdv9vR*i6i@#O*M& zJNKb66#2drWKd z@-~;p%+dkkj+lyQzek;Z=KTY7Ch>>k{LQg`8L?6NiP+ehrs{M!O~uM&SMF;BTsCN8 zvDl;^c^uDL_mdkegPCA?nG0%p(dZI3l$piZBC z^1ydLFw*i2q*XQ{kA@M4bOAxo$o;=zQl0H?(ZWw&X63!(6IX&>3 zcNEa0!Eep&R2!z5d!>>Tvkt=hRP5Rx_RcFJltLFFDrV_wQ0%PbWX%l_AyQ)BenwnW zSUaM^d7##Yf$|u17+qyIrgBYwXoeOa5G*OJk8S<;Quc?2pNxnQ!qxjh|C!;S1 z1(9F9dNsk|{KQi*Z0qMs!L8#Kh9Py|?DQ#}uK$=$%lATU-D(>j!n3|t?4Q;O9&y5z zrO&1zm5bK+1%Pm;PY@3J@%aMoD}eC!Z;St@Y?LBN(<1Wq8Qm#lsfbb1ZhLP-L?6dX=AM zt%i=BK*!Rq{h8Ai8uvZUwg4L0CdUoj)luRoVsvs4jST>jET8UW@g7jUz2P-C`80^Gp!xZ+_uQ4hmO218;-6C$rLT z7=H8)rAX=0h!?!sANl{XQWt4N zlz|~hlx+VdX=Hv{Z6z)(#v3{m(VfvI{NBMZWSlq*aQa*MzvbU4Uw!&Rn=)-^NkOXU zM6HmsQmV}sS;s*jDu;H!0HM|?At>UPU&z(%n5m@m9E1|jL1=@6fOD8HseOL{mxu1= zn7uMJvJ_%=8B?f2SmUjIrx0u$eK2%|o1uHA|Hs;mH~CX31d;ni=6?!eQa%PT{s_sD z?43HwfHahOdq-KTN^=JXH{6*CPuX^~Zd?vX9)Y!u{+p`6=@t=cS>fT~lYudlsnP{! zxdV%}Kn-SnZlOHHUkKOZ9}QF+G0<>L{calZa0YXNJP5wpOE=m34uo;nxE{V|%QQAC zdcs%=I{`)you7(}RpO{iyOyCry$iD7o8#Poe)a)A{{b7M1ly&+r#gL}KurDm@>GcY zE-k>%P3Ukys#}gv&*Wh5D@-{3`i(GnBbhB}PL;U4OULLp`fq+O&|hA;Dg@%D&C2u4 zi)5zz?*Lhq2xKXmy#mPUO(j=bX3`gueWB@gePUUo5OK$9{KVws8az#gJw1jVZb_Gu z3|m>h{d8%)j#KT!246+e5!Hr`Y{{f>!7?(Dg`XH1^N);-$uvYQPO-@Q011wx4!2dg z%YsXhD7yvaMkqb8q;~4w^M!`o&Ag$K|6PCUyo*f{M~UbN6X_!z%j|&>NsB0pr#=Tgb?33>Rcx!ss+t`iM-2XV%6dLl z$dG}Xbhe|s4*Vez`I6&ZG+?BK3^#Lc**} zt&uUOK$glc;r=Z$`XX7XDeIF!u?fky@4ruUpxRc1O4@sS=f5vBK--D#v>DJ)Hr7OR zSTAwvT3M9%TQTY%xA6Q;@A^dreD@@1Y@XNW-e})D%Gjr|C;A$3h}zAU3J>|quQ81W z?Z24KK$@Yf6hhIu=@{$0^D^G5SOHuNe>2wKYW4rH>uJ7D1)Y{32#8MyB2#vE6u<&G z3ZcpK{(F&lJ8kQ>*JFDnl4O*^z7d>G7%l`Ing$MHAG^FiauX!Ey7m)sOQ3+hs&St}!ou*>GSAD=2rR|l)vM%l4NC4k@@Fu?8xoNsb)4Xf)Zv~~+sR~k z`{v|o2jXG4`CGQ$-n&AsUtj$s#Sf6Vck5Tp{)iUnuAm!yKIK{D7kpnZzO7#yrB|8r z{Um@uwAjMP6g17CN_L%5KoW-Qb-=^eQrnb*{xqltPX4e!)d%EOL(d_y%YykFVbHr7 z((J+}O`#GJ$(Ee&%)uy^Q*u|9V=uYK@fQJ5~jLYCsQ))&mIf2avfr2ZfHA7Gt7ctSi9qDJ7i_0F@K zN#=6G^?>%s44SE;)ra4HRlD)2;Bv+AGf;yvfqoQ_-sb!Oy2GwFNMv64)Hv;tP4O$B z+U*fvBT(rz7COkM6YusbB5E_=+j`NdA7%kCVTOSk0b}u`wb6Tf;lRDYvdItpm8@GK zjVh%p-0h?D7VS6Q(H&_33N)dLRQ$HZ=;pB$zlY+QQta0ihO=c;nZXLByR3l68VOn! zR`k?(=90T+0dz5$XTC1>VMt`YtJ^6r#cc+T^nV#Q^hHv787OsT7Ed%zT%7Y9ypsa4 zmGgTEP48cj87C37`{EuYol>t~v7MWtP8MaU%O>py*CEhG1Lpm1n9apF&3cgcvXd4x z6;K#qb9kdjr0;HF)kcRwJtvum@~3Pj$udVz2=Mg`~Q zfv5|XuH>sn^(s0L0jo28K9iZ+(pcy@+&If+3sp=cT3A9mgZ_e6Rq^LOL7E}R&k#sk zv}9!>2%Oq%fCI@A&cTzBbknruxcVWu`=o1Ig}j(h^EP+8Z6oet|IOEeOGhg~CQ9Mu zq1Nx43P@;${Ch^vL|I$nW0c`)V+N&tPnX^IFci>Gl@D|!5HUYiAVkbN4}ughmO^-S z=zm&ln(`tSc$mCPt2B{boVyQmH?zCe9(=hkR%fpuMmx;kFK7b+79r8}dujwoQS#=R z!BU%nzZG=o8n_;hvnKX5@mj~t2da5vE3@y|;mG61;t(-}vJ5*NG}JK9($&U1hw}eJ z-kD=~J!l}nl#t!jJ_vv)l5MK#-bEvtT3-6013$Buvi9Kn8$dk;K5377=VkHZ8e#kO zOK<*9BJ?jxZ1FYXD1OQ@vW8>{2ffCWNQO%`s9YU}h)o|83`p<1h^Lc7$(ldN3(hgc zK&}%3x{h`8>hN31@pnslVnB*m(z7+9c?tv`xxWMkfpv>SH0Pc!>v;CS8@3i+5t!D5 zaT@k^`0*@E4qpJCP%guO2;(#3Z^^DldMkcI#pBz?3@VRE5(P6f=!1R#h0}0=`Y?n^ z3O@JPoQYd$M|%|D!WXOs{6oqEzZ)j`g?fVobb~!SFg^SLoO!a|oqKvHFx3S3?rAIJL#JqQG3Rq2@lHQF8WqZA>wE0E09>8;we$x5Vm`%?)W zV?&l65%cr=1wp65px$OEtoKjxA)Vn-NP=l$JtEnyC7$>01B+v1^pXlZ&W^A)5|C$M z0>c8(&%_;mGZ3P={@fVg zFVgV91tk9~y?w@hE?*Vy-Vtvw%`9M#7Fk>XofT_8{PE`FvJLq)

i*SUSkw=3S+ z!WwOz|Eb#iMVu->I^$jcH~3UG2buGSXeBKNzGdr1UP z4+aNwWU)Ea+)Q~+Rrd`*z`TqCY7VUZnT90Z-ev0mRPFafpjsf{0Zhzo*Hh956t z*IZG;^KcP=8cn)lpt!`ef`V5JJ(asEA@BTpt$8^K2$nuOi})W7YU5)rFJeqn!F~AY z?K743{cMgm)wVosO6OvCyU)b!g|oV||4L`&1EpBgYc%-);jT4svu}iF?+*1@q56To zd}Tkk=(J$xHGe3)%YLg4%3|*~3ARjXH_n5lkQZvyUAed5BvRZ6^JDj`mYG#O7DcGz zX!Vye4Y4|hd2@b0H@od0s(D(b>nn8hmpN!NV31RKGy#@4Gnl!X{p9(&q*)7LNp&S| zeygx=B>CfD>3~_Jp>Sd@-q(Eiw$|4D;Vai`-d1t$Jh5x$p{CVQd9I)$nRLLwdlY9|xaEL%zv)Ko#Fg0UBr)15dbnxN0m*kAuBg2qDw*w9;d~asJuf?up7cKoZ#(jlPC}aiY>Pq8=6*;|eEUtU@Lx z=pZ8;1UloIUqlCDM-B07z*(yir#3=E#R%FWY^l^VJnNJw7_N#8j#(Ja7V!M|lJ-Gr zH-5HAA$9ihcBv$*UqIHgZzf+Ae)3f$_gI)?mqcKkTcxLEF0)68j5<-ua+2Adp6G1H#rkz;_bjCq)!gjDp;0oXHY3~^1yvBLeNoNWO zt3O&aZFkr_Vd%XF3i61+54K8(qOZUuvpK!zpd{|M>e#Rsbj&LFf`nV3gH=EJ>$(f) z;f$dk5nq;~C)XtO?T9uC;$x9pFo1qR7D~vhj9|H9nuN+XM_b+kmviDf&-rRMGFB6D zkV-Jdd0{{VfV5orEw%fB=ye5T#tOAOK7WC3&G-<7#b_W- zVt5jZdnJ0E<1AH$#Q{OuF~(W8V9&?*LZkL*2=3{w=}vdOr&B%DZV(eSANBbip3hdt zt&-W4q(jS=*sWj6-%BS5g#@o#Wp1Lbn*4`X_c3o*1;KI!kl3#|Abm&j^Q6!#3V~6hQV0DxSbl zbW;bCb<>r*EPp|lWG~1_9VNouJgd^2iJlLI^%+B{yEeao@Y78iDnNRY`fq8_!*k_6 zRRqjn@PzTNPjR9>TeK2wfCUaHCoOzDkhwx8cP|~PkupGd&#sz z2I>F5iNeJls5Dr3U{*NUVnLSl>b!|#kqOB{3dO%@jo730g#BJWkFeMkFmYchX`@bP zBDErnNH)-rxAJH>F!(Nuw6ctdrB8KWFx*jOmZ_D?)5U`^B>%I%@DI9XZ?%UZ=b7ry zTYfXP9varhf|O=b`&^#B8k-t~=MG*&MpDpT<8s?fTOP*7m)$|ZLpgiueK|H7tW(0n=U`!lLV?U}c1r z>&rER<>Hua5+t+=ru&XIyN#5qeJ~^YM~V04=ae)Tl97PrBf&2d1wgK$yCw@hSXK%!}J&zei8n3c#d-WHAEajiggY~P$ME4qx+hs-ba z@;yA5uZq)!GEx0fAVi?+vOl4gU=>NpJHF)QKHx@q$-0ZSp+0VYH4-8={oEYKf2eCi zM&_1sM=*KXCi+kP-z<_kgsf?>kZL|Z^Zsp15!Shs+21mr>(tSRY)mQ1RxX>J%p_7~ zM<{shTw4-8``71}k;N9t$k_A2u(_EqV(XLT$nF>-fwp91PIw|AA;F{B*fa^5#wt5k z*IF{_IT&T(Y+o`Pg7H7a>Xkv6&2$f3RmI(d9u<#3?Wv$S1sFf4lJ!1Vrwi8_<~<;e zn(tb;VcLDSCJxm#gCw(6F#biL%ftS%W~SF`q<1dpJiB$ebh@Mka!Q^2z7;Y4bNH#u z=;GeZ_UFzGS^p9+X&Mk|J(+5nqd|f z+Soc-1&~99%Q7m~pQj@Et1M|Wz1vH^E3L*z!9sA0(~#d@r_FxX0xM`vuJ?X(p@~At zyq-*}ww`)2$R6wU`wBMD_@w6`ds_~RZ(~~TX0p+0eG!9W)xyY{j67=ss!_hIAC|qK zk*#3nnFXBjYO->xCE525Z#zv3b!sj2aMjW2_eJi$zml_mR1tPZkZf(-;oZku5?VgGtf3>&vK;V~3<>-v_0YmP|IdvTo;c z8e9~-p9-00T71}6Lr0c)A&V9orwO}Ue~$NTF-xZ+7)M5+qR}yRCGZlUYj`{*k`3W) zfQ~Bidx=LniZ&Wsjz}48dE$&kvMOCoym84(%H!-b0Ip2I0arRr9JMTwd~R-6?$f7F zJqGF%2BZ7^?hM?2J2l!B2b|Wfl9t&wu-(L?YI>m3#;jho`0a{xxcu|&_UWgLr8cyh z&%6vkwqYTgYsyXy1fe*;vJERLx@QJ|)c^I@sio$?qjveXlFs4(bxxRY+|?L<517{A zuX=qpR?QYn<1UTg@V;hj0S+uf_S9f?$2I&i%4S(D(gJ z!6G3`+;||^h=7_0Oqw<+dFX;rY`fI8W3YkeeOpQOr77%Po}4`^xQgv^XPEOOCrLKy7W^_YR}Y2N2{;pB%wILgRHNb69pa$ z56AVFpP8b*2dRHsQ_{oy(t2c{PP~B;tdK!;z+eoRkYQG(00C1{M@pVArHg|glab(% zN!*!AgZ&H+u*JqY@lLXBX<41IsZ}JhDR1ypruR#^#^}L_{p>CvwA3gfx9N5Af?5=S$K@qVL+krkoM z)ypb)%5rLWsz`RU)U?S<@~YBcq4<1XFlxy4<;sizii((~kOe0H+cfGqlpki1rl}cz z4ngAMf zzGtuPLvmoQ2-m)zb!)>$`J*{Moy2Y3@^i{H!^Z}U={9etslGdYgf8s)=|$EW8>ic7 zYJO8$t)B6Ul*$qJP;B_WT$B0^!Mb|$QhU}>Y?gtWbVi-m!?3gVK0CwiTuoz04)3ex z_l}uojKr8HPu`!HZX8MZ1j4`zyXD!&h?|Qjv0q_ zBt4JYzJq-fdQ7$5PMQ93`Tj-u99Fq%=}nK|{9G<0UmSH)o!uX6P=BC%H2tcr)JRWm zdw#4KDrP5TyK5AfQgxFPBmEtDa(X8^CK-N<2>*+{?Fw=+hCgLwOI(dAKTxfzFO`aE zIb8RmnHf6SuuUG_e^b%bv-A|!PK_@MsLuKK!>RXwu8iAsV<=#5IslBHj2cm~_Qh0B z!Gb@{64-Av@-7y$D$lJ?7yB?1*RM!G){}*+pF$RhH;Q+^zdVtS!OCg%ZV(>4-beek zkG3SI1P`kQc#HDl2a(-+gLnT}>Clm*F>VUU6KN=LbXc zYbIXhJ=xgQRjql(SDo_Mfd6Z#34QIQhcDzex*_X;2*Y9gjIjTW7(Y|R)Q z{_jlSUA367eCw3{vKNt2yx}~|;I zfs!mw$&fEYLU}K322A1KG*UJ<8~?cbY$Ngp#~togXpOpd*?!d*xyNT)**I;~Gt)20 z0#lO1=p@uMPN=irWfeV#<#pCxehuQ}85N-^75tKbS);)}JIct@ktp?<3xh4E0*WvX zr{Yxb?G(jP`p+2*5~{3dt3gFAsZyO$qd1xC%Z1%bU26Tv8i1h+eDCi!wZkPcTWn$O zhpc-GGt~3m=T2p^R=qMNAC6f&HmR>tlm9e?KW9#{73`s5S67HzABM$h1PYQ>M8kTDP4 zuZNV9-JB?iyDjZ`k0uHet9_jEFr1GY_sz`lH5+YvhWsm7^*qB235s%LOE2!x@?a9)E9j1io zVpdd5izBz^I0ltFF88*#jk$K;Urs}}q@>0uISKG_|L5>=D9-a1A5)a{s>6MHk66ON zNqz3%lqhSVj+=M52%tbtzY$sL=Rsh164}<`C3(Kpc|p~rw#vEsc+7B=>B_!jed`>C z)Er$Z-W9vORf;>HW6vD#i;vV|a_2atxkT<%hXN+KHcpl3PSVQD;=UCQ*rf$qWyj7< z&l0_Ij#?YjubCF#^D6Z02qBo*v!w5dWT()x&NUBZpJhaqo@(+Jp*L~xu3^g8(gxK~ z1%u&ns4Q=YNRo%PP^v-=F$#`;~c z-jsh9eR0XcwRx9Ra8G_LoAxVf^^rz**O4~)P{k>?Rf{q?N8)WYsq5lt6TMHv4b)|^ zkOIA{quFwLZMnUz8nCWo;+bgaBaLWP2-sQ^kqj~Zv0~k>jU|Knn4vn#`3|S}j=a7L zoFfrPmYFggbD-$_$dKl+3}xl^G9)-_>Zl)Fp35P6m38LdE4Gu_|00Xso<^>7pVE>$ zELP{%jDB%{%x1sjOV5{UOg->%%C8`I-5>T|OtYrm&t@QKlfA@`eHPT9v%Bo@J6#3( zI^LI)B2BH^>@yDC7KJ5&gJ%@{%!pry69yTnrX{I<8o9;oGAIf$FJ&Ck;f-1o3Bt`4 z8hL(xEm`K>a>9RiCZ+PyEYnR_uJy4D=I({Eo?2S=!t%N%!4^c_nyGAwFdt!R(jj-7l9r1jx zRQCfI#c^9OiopSa8igwE$xmaxtwoK&))PP5lTWylX^7R6k)^W)~=z!HOFnRK}9DP++Hbi|-oEVDvDyy)oV+;O?jd4Kc4;jfFCAC9pP-Tktv0R{^ zWzRWuy8~0E1>2rI2YEYjUq4?TW%BUE%_&MifPUD+BCj!nR!evNDw2v1?EUI4SkbA# zd8TlkW7)j{g&si0DZ}zKQ}VAtk}XVsYkQ^2>JY-tW?is2_fx2?%!yDt;TD*i&NB0A%YCA-?o{Rv_#G=vomvf% z^K_z=YV}2;lx^TpQ_O}e+8UB65Q&KiG7=kEPoAkv^8}g}HCXh1s2m-$I7wz8SEOZy zq|4eoKe@hjfid*m9}nd10v*Wcju65*4;VS&JCM-mozM)|!qh|8`*e+_M-bn&Hg}{& zq@~cqWyjNn9ZR7YW0cjD_vF5QS+q};l1J&O_|JvW|1`(w&`PC;zqBg#FHo|!^Q01w z%r=T-kDSNkm~tb=Be;dWej(45!#a>;xqoCA7>8>iVjKiP8b{~M&5e<1;;1u$q3(ey zU>gOqz1hEUWzX1{JZjygxi}~-w|bYQKCJM%PT)Kwm?KF@ghT}d>IQjm9uw{YJdZeW zlv|=3auD^d2KBkdsNwA$CR1k?!!a1S-7xXk7ojIJD3Y5VT376f4eNh%$ zrLg1A8w{?v`sBtxavrE?E$-^b*WCAuqS%koj`sHUS2ktNRLTW76eFhMY6;##ooU@K zORf`S{O!znb@Q4hRGaO|$@*OzonJrN(6{3m5QNvO$sR>{XVOfF%5izeZ+cncx7wJy z+;A;8i!Fj`jnEPH;C3p@lk~E$dWYXwP)d@ZRP=9W~z<#zKIiGgtX%ok0QoiPz zQzGjfEHlg~NWr!~W3)HF)DyMq{t8CK(qRGmP*qi2@1d9NO*552GD-nYlENN+a`q)>Il-tB3MeOW`H;?nGV3$LNx(qy0sxvYK8^fbF8?e2hkY)e+$wzJS+hqGoZeP(#U7XN8I_(JM*4BYBic|t5nRmAgO=gU*`ds2NZS^* zauVXd4xMhIbJWQkzu~s-BC<@H7 z>^J^vmPe0(xl|je9qf9p|Gc?rCgyx3EF`pYd=_HwFC?t_Hqoc*qTpSilOv}$)9f@O z==|Oz)#UT=YE8LEK7568FcJ|^a-=(Nm*>6zQ^X*acx0ErL9O)xoPxtK1k;ZFLF`W@ zh-pUNZ&K^bw$#(p+jjzXyQ6*jNSlyw;CNh1-V=;05-pkw9?e1>;4Fe;Q9iiXfZHSj z#uq%X*atg39O&}!TlCCg5d(v2V>aJ7)Y8E?3`-$6$#xTXa3XIHUvsW#MYM~9Dma|| z^7v2b;{n69&E}d1Y*fk($Zk1(=itelI{L1oS(Jq}-)})?t(Ek$6f#Y!Ww zMs3JLs{E3N^e?S;w-2)b5bFFtiRf4i61h})-YG}V4*4ka&kQg)oySQHJ^0Pbk-j?M z*SDd{`3^j9y_4!NV=|?G#xI6=L`Lvt?Fvf_hiMJSDJlEJI!~*NrV?T`l{XsyktS~w z-igEuJG~qi@(T`&q4wID$0QW25LZbI5my}=c^!FvZ&Po|;~}Cn>2?1%QV(7l4yhc0^n7hhY!Me#V6N#^Y?;jZry14lh&Jni^%aWLU+GyC;_OT%w6Q zrK;3v!n%K5`myfkUt%VoGYvf;tJ*g{a2={urF6D&>-Pyu(oQLMM3=iyH0XE*3?uYV z*Lqv(3la1YnDuVQc{NBR;K%36u?-%nweB?247813wRq5JpV!qS-Dzgd#-Q>gOB@)> z*9SCC=j6NL-7>zlL6xjrzVgzT0xU4E;~bWWUp=atS!vE{>Q90;s+wN~f2v|3gzLwP znENy~oP8QDjw<-NiCv{n=;W-Mj9pB6Ft#lwv$8oNMNgqbNz%P$$L1~ZSV$bgQbVl{SIrRB zi;E3Q-d=+q^E&dxDlW~wnFRE?ku}q39Ar29lOi10CR6DnfLvB_-Ro#YrXg>gfClDG zmiljN3H&d!ZJ4RNLRLXioozm`CftXX0dD4xXCqAVY%9sEq{SjRNVG=f!PvjZxI#TA zxXT=@0wddztU>jkPTf(gUw!jCWN74nlsx|_rOyxV9|DB9$MVirTEmTa5v?#0Bp7ZS4Q!^LkbQW-?^*5e%oqcQZ)>L)$ zEdHR`-)uuFy-o$|_D@{G9lhByIbSX+dp}HiYw)homHcyXHGy+rzX#XXl4$>e>1+rPEwA&lAkV>>bDDFDcM+oK z!Bm0|{knLbnX9rgZfC~>V}#*W+a(8&80)RTSnk-U)Z?$3@&t1|ia&q&KWa^1L}0WY zP{NI)uRx4F+X%fv6%y`8%uD@!a7FK1iw)`!F_bJuf?C0JJrm<(to)We9H(|iJ>z)oaH zyPlD5rO7JX=dBYX&@qJU8==xi5F1_n?TFu;Y&TOu_0<_L(ZDZcfz}b=-a;8p)2CYaxriA)A?&zP2 z82C7{9dIPTpaV59OguREC=+|uiiQmgHJ?<(;0>|1waTM>vvqDMjXd@a=p}acmE1dH zhhW*oXOtgbc0ZdDd%33?(2ou5&Y!&J@w_ECsM8v%3Ux5A>+){%Z_m~?M}!X`F>KzC z%D-qjQob#9?zLcCk9d&vhrq#1E{T4h(42j5pS!rqxkKWr&P^Q!EeG!0?Jzi@Iw5YF zfl^C95l}@MnF}w0)c$~j#hQL0?$L{4OV-{TJ9vYzB38!GmU4$tf(}lWHxGRwKzD5q zv^nESEdf3TAy&?5D|ETmFH%2z0$x|&{v%%bJ_Ah=VL)`lGiRy^Q>qS4AtHnv!G|`t@@v zkbf$l;fK6q+rf0RMB6xK6HD83hiq&68I4bjb&L&O_6Eff4L0+MjA|d2$==iWA0iC} z&-s*SCK2Y)fsnukDw|o(lF?M91s$ypfq0oX66eKDx)< zsJ0Qh0RGX)WDcvmzsU=~EY|Ky2lSu)ITm$M#N$J38}U^m1P#MVJl0tFWs>X3?o#Ew z6U$?XI@eEEm~f%-*sl`-{UaS)er8-Z zv>Pji#%94u;O75+=S-zxO&W8b`ku-(+}Z>qD5OA8wEf56_wqk0q7&;%)o6Z%wfYut z`Ml9jg2^DdyTnmup*~6hhh(<+G?RYzxW+TMw#BDbl^!_Vf3>MimF7Q2zGojCwQ&bB z^II_R*y^{JDxeTnA6{EFV3}>tf2by+q*i`e>Rkz|%U! zKw~7^N3UT98(dFZb^7EDn2P`PALiXG;h43*;#7_ZN>9d5KDCnQ;b*Qw+^VhmFNCsE zt-v)H)GN$U!ibqAeIfhGPR*mmiV%|H$z$p{P~V2tg*0LjT}0;OvC^DlF^Fi!b#4PW zv*L{gIDg&<8Np;1V~0Zs+w?nzgez5$gf#FhzH=r4J|MzCzmz6T5J&0aEJgb)#3Oy$ zBL=0WrFL?CmzUn}JLE68ba)cqGE+IOr2Mt-nYctCr1mJHomutZ^bLtgNlDgm8XdNH zpR?-YuQrC8a+V(^t3EnJVeQ6Em22v!E)Qc0$NZ}As{^6qypQ{L(eRgrjwLdnh1;JK z2gSJKnv~h$yriyHYjX6p1KPtnmetV;W2a&(;y{klmyC9v&8LfKz$eANsv##M%xjXf{j=f(n5M>J{g5{`dhRubrD!XQu%A*hs5xT9W0 zbj4>g2Usl^&*G(xFIRAaY92|KY=oyCg5dmr`_!H6TQjWuzEL(PVfM#q6iIt}xcc5OPkgSWQ2Hf5Hsx4j@y(WUXQ z%p`i-Ks;7Xq+9(Z2q5Ln+0qcU=u06x#1S?17jb@*v;=zi=D1wsko|nx@ssYaq$CI{ zXSq~48EI`x1=C{MxwCQp+C5h`8saiU-sae0+m-GDJquqZ@W*LUQhBp#67QduwC{lU zEkYf!h_wXyNFy>Xe^17gmaQte*VUQzy$SdG34234V6Jquz>SlifzB2yF}&3 zfXPK>u5+A6vVzdykni2DkNi+lV!+Wl8XxnbOr`4c9a~OShqR|PG(O~EQKu` zbJj{pw|Z4%aI%PCXzfWF46`{SLF9izyE8M_jazB|l4Z1&XglNLWcl2$?tG%XvFNYO z!UqU@Cc$Rbc|2g2%-yhWIdDH);#h$lyte;RZ_W>x1MmoiU4R+JBVAF66PmFu%TSh(4(P3el;Vr0L9D>uMZ2 z`sz9GuVxb?-G^8c%MQUbvrLVVj@f<5R&ko2ZOZwgs2Q|vev2iWIXP?ASV z-hStDfBTQ~DY?9bXVYmL^Y{y3>6pKc*|J4?o*G@?{yQGiSMw7-YX~N&}naOHL|v zjXOo9;dBdp1FE;>k<^DDddxCu!q}H!$Cu0dckCwXl*PbYIFRBa8YY38P;Fpi94bll zIs_~6=ke}S^_ngVCy?}|sz$o)SX;O--3`=p5cYq*E9A@g z0N4&DKY%Qi36nvff*wBI}$NuyB^b^dPe_0Tr-zVdMBP9_Eor4>p;`${mW_;gRNH>xm zpv-Y8L=m*+V^5lo>MH4ilZcGz`+yN+RJhBEJ;oCCmr9`-1?t{)*V3=qsE!|1!hUmv z%4!o~pZ-%7h zj;>r$REcAH6Yeq3;&;wPU{rCjlh8aSz``#gv)ZU7Q&WVQQnMn_m>O>C5I^?1Iy}OuVfBE9grP9hwpYG9+H$$|4?3W?fVAJq=zuljZ56N#eQIn%ULaX}IJ*v46$7oqWHS0+KqP zbXLOPMjr^opgC5u#;bVxo$ZK4OnHke$b%gl+Ery6EbUoW;3-KIB8DN}tB;i*v}QlnVM& z%-sT==Y<#a-*Zf7Bi<_oPAsqMiNYx7`+iUCK374ib{iy@xR5}6|7Ci!m`E42o1_~! zs$kZMNhu!g?op@FiFef`l(3o@Bpx#U+K>F=f zoPD}QX>nfSXY9lodq^tf* z1Nbw62EKs@YY91yt;xmDPTy)x)O4aW10;7MpW;B3mkirJ5qx5DA6ZAekr(uc!7J)L zcNShzhM-@OdhJs6;C>QlrOReMz>AVroje8P6W=J6|M@@&3nB(Y-1n|+o3#>lLVO-$ zBFARPlgPtP7WgNPEHy7;D$1ifGVxPUn5-TLs-&{^5MWESlHB8i^!kZa3Vcs+e_S%4 za2B!HCP7=QLYL@FPp1()lEGR;ud3&kkp)iJL+4(P=`tF zc{}yfjbMmD>%ANdqIjEF1zS_Uq|=(8`F737ie$GeHBVz21rrBb(eBlGW^T%lL&f9@ z>Q%c&ojMP8Zdq9io!M>;9{1?4@^1M%Qhbib8Yr#z*)52E@4tLS|58X^cGe>DFlWvE znX#Js6vaU}kJ{!JVj+>11GEApoXLhs?npSZi9%mBR0qeQC79#L&4$qxT7hE3ZhuB? ze3!7+M7^uFN*2~$Q%4HxF`Z}a(-+w_asX2gD#|P<2z&HgmC3F0hhaX+r$W_|Jxf(c zZ$!J8k;CNH?(y=cZ+T@|t#^I4D?%Jkwpg<8jlPweqdm@R4JL*^3p=gwM5ZM3VZc;E ze{gabPMmLPNzBkNLkt4d_JZ~qS-bWS?PqHOZI52%z6lsc4{-%8cOP2GfUJWGX`QX6l%ez^^=9&wjzzV% zAGABORpi!VGaWkQDbP%zUo_F|;|fKS_h;`U#Ut^VjsrQsuHxC(vD(j&G3pQz-GR?a z>aO%h=g7 zY^^m7k>087wsd_cHr6&@vTyrwdM_n00CFgZujg%@+OMJAK9Mz*eq`V9YG|O!u^Wkt zu*-mC;4t+bG6LXBv;3-W{y*N{G_1*M3ma~aEuL19whmMfs6|9nq{<`^NLvRA2oX_` z`8XgThR95SB(k2oXXE5atkuOnmzZYTx&?=X$?$ z4Eg&_S$RRYpwfEV}pDo?2AlWadVtHZsBb=>gliPWpDAtvMF{;r)V%C+6TyD zvnX}od~S95U-pBZK^ar@XN#5LrwrP*gH$IlepaU{1m60G4~ch-s8 z+uL8A@uEY)KX%v3a^i-JOa}d-y@E@7ubgWkulu$hLaC>`wfE4Up7cACHGd>*zn6Z+ zY~P$^S$7!}RGJ-;1eKf}z*8NRL~#^pTep0``-uC?1NvBqnyH>-FB?FG-7vF_$oI*U_^FEJA6m@jb2@*C}$7DBDbHuF!#3 z_+r};Lm+OkkyMQGZV#I>`jM^)0y=`U1G;_uPtKz|*bd zVYMCc+hoNb0hCon=^_?xNlpQl`Uv=8savXmyDfG8M+PWnc+P zZn6QVmaAlnH1@X(ZsyF7!>f_%xn8NxZ=cO*KknDLKKBbqW2R(HS8|v#ylT-1VudQq zKT2*QKfa_TxRBPk>Ba(-rL_{J^jHBo+Dh0}cX5&N6sVzu0l)UB}n?>KCr+nfuevE{5OaW;mfMa?T&GG9~TA{l(0p6XA@Ax z`{s&mMeF%`G33I&L{RKHK=fjjkJFA$xiOA<#V>U%(qoUP=@fHAoV{-vB0S?Yf;4+^FP5f{=a_Xn`G`qhol2$egu6n}k zwxB*A4gD+0E=--h$tDb)o%sUXa=9nlz+Hdh&TxYFQUF4ZWt}utdhGY zGbvVMou3b?43qZiuOA5v>#D6!SlvU!KaCwugdHWj}ZmsSD;-URCOrFXD% z1fqPF5Y2gqo6V&ak|pbk%jbJi-GBPcKn}WBTYk2O{Bs1T(A6aCM4u+?JT)H;nvo7j zqZ#SlTTuinyeK~G6jjQi?bVu#%jHMTX;=(intuR|g|h93%b}?fK^HX2!Rg3q?)Q;q znQ+&{CwbM{QNxJZ&cG((`0r3zVC(*2m%@ryh-YK!?e5KZ+kha*4Uea}k(>U>2U{Tu zDXJ{ALN<;o5u^#N0!Qos0}Xi@rBK((TU_9PcKvIwE_ps^6WpFW5{S;2+iLhaRR(&k zw6R@F`!Ze=!HY#WQskEQZNLesLcL%;U?4jMuI2=Q@02<&_5$#4RBtd%A6>n>jW83g ztqiJwgyv~`cKNNd43~K%eoI?Iz|9UHrn;>=BiFA85#O^%8%(O|Dx=;umg=@z9yk~) zL40%Vx{%YSvMF!a7er7C)`150?WqHID#3$wpm-Hxz}8;~N4bP}FBgg+so|Qqlo?~O zgoalZlw7cXY*N{f+@L3UH7TkLw;iESt^1`f_5J9 zW2)=_9O7yj{mh3qYTOTc4ZuzD3v~fE#q1^du7;a*Fwm7zZgQt%(!C-zbm4H)TnQ@f za?30l&UNTbLh%w%OL~h6VO^9R{PoIyTc#wdKudcSefvYKQ0Z4rjj1k8?9kzoeCn0-PeJlC2;> zFLU%TRBa^z*lgx_fG?SK%n6V+BgPXiq@kdI&)_RiAo%l?;j6Ge>a8H!W!F(l?i|UM z1@$UcnGfg4==D5#&J%jsTi-S*@X-e=Ls7HsGR$~e7lLBT;n31Hyjz-@KKAHifZ_$O z{HPR)z|f*zQoCOL>RYU!XhcD~^A+ zBHT>&P}GZ{HAjP9kOMORsh?}J3nA^d=g6!Mz4h4cbU;k0v5aa5V`^3{AdMXSvC4;8 z53%%`wdd(7oTG=I>OXxxJsEowoqTeuvg2WLgvNaIYa>(xq`ioiwwtiJBG=Q+DF2 zqE1>EeZ$0Z~&18o(?QXN&N-eE_|#o#uy!c~3By>DBlfdZIybRMDEipG13b5tW0;XVicxiqQvaOMWmdZ}wc&K4@R zjUJJ1u?;-aCxS14JZPo@f5c@33^jI?Zg#Oh+dzxDqi&sIYF-;~d&&FTLKHOAU{8?D zG?2EWNHKGauhniErW66w9lB-$I-fVgXV9jNK|3>NeyTh&?6|)2Zq~+VQwQlyEr15V z#!oDUg$F{j3e84sS$&(?o*%OOO zOAct;rP)3BOp3X2d+@`-t?sF}_f<^)SUHhH&6OT=DIl@a4n{|H`s@hy69*=_*j@4={A`t_5>T8m zDcHiRhq*P{%u0qj1}~<8woqxd@)T{1uUFk1O6s*O8^VA=7ARuQkBvUnfbN%L{m97r zlw}XEBuBf|-wM=2Bt3}_leEN@IuJmMs1!ReC06-U-4FRC*G>Cz?ZcFV6v1}q5iqPL zgNegOWe;oEq{mMkyToV=TLp;NoO%1Er4!d%oLhb= z_5n(LB_wV}9%rqfRRne4!Xc0JQ=PRFh)Gq>3Far#Hh*vEVnz>qURF=H1xx^#!I$6uFEQ(=(=ECU`=jG0ioATP)sdG^;LUshw$*}9uW%VL2=`F(zdif9+zr$Olu zGkguu&~W9mT*a*Ffk^?-_1*`jK6#^Ejws7m>|6%*oHF+}|2J3G2C^G^E(54gbLE3G zodCdqqzGO*0X~mqQJuk$P980MATp(z7CabvXj_yM&t{DF#oR5KW}BV4Qk~lUt)5~E z=eNy4k^t1;+dpMTCX1(JO>|Z>{koYRA^pav&Sj z4v~!=sCmPA7-wZZg{FkIR|5Tl>c`WSitzg|x|!tDjx#T}cA~DoLvsZO$Rh; z5FP@Zrr^uLBN#9|Ruo!)KSS%{A$}OtxLrY~Kd=?u08Hk?=RsFl=JKz%rAdOY4kaA#BWWuE z?4VsOEp(DJTBn8eVe6rm61-5MG+H~yWua_R2y`NQ<^V-ASzv+!8j7(axtq$CMN=v! zenTJ21%J<8tW;^G9B%vkN&u%TQ@?7dWfW*c1Opv_oOZmZ2M@GLMlI6lkh(}#5Sg1+ zsUl0HFMh@vwQ9ElZ~4{a_#AzPVZvBx%da3idRyshJ0pK0l;B$Wcp?pw3yVF=@ z@%Oc5eh|s;3GcN>*&xkSd*It+8d`#J+e6v#!`$}|T<+xkg<|F8Xz}R0}xEy$5Y7WWq zQT>3(Nb8~_gWoj=w6Od=@L3;&xdxD~Wq{CGSp$@6V9D^eQ=aB8{PM#2MWTLm0e|aI za?UPU*9++~)(Y2!5y!%J86N_KVA7fKy&sM5dxeHXEXa^x7hq?7kd;!nZD zoo4;4J3(wH)pxJtRefyj*QW}|{IR*;8emz4Kt{QB>R~Kq{2V=YF29!qgyxKhZcQzz z6*oOtjdwK|&w;2Ca#^%6h24qjL$lLHfe;SLeJ`ADcs=@ zB>HIvp{Q)p{)TOFCO~X4h%KY9EO_0Jm6KnVt(|J8K?lN^Tl?Hbz}s`^j?RWxkfS=B z^YSh#@^$EjQ6pbX=cPEUIXSVA(0+x8BP=k}CXT?S2xcnJvq1rBd-d?af2ALI3JvN> zPcuv(+b^Cc2H|t!P}~H&;cdPzwks*&X5;Yd^M-E!Zpkaei!Ox#p%z9Gp8}M7Aeql+ zg&5&X1EFbOdG4rc+Ea#z&ahMgI-f=~B0bQNUE-f-w0!A#G~W92i8KOqNgtn1@#-B0 z?cG&N%j7$OuH_4Xk!M>1`djdNm@SoKgyZ!<)iS*JuyK4vLG|UWbVFYIWL+tLsd8BC`v9Z zpy*7_TFO`_!fz9l7I9Mxul3lmdxW4+2EyvzQvTIsrXn{!GB2!rhMFt?pQwfY+xg2H zpnCnQ%k(euKNa{xLc~yfL|;HN_qZ;ZyYDUdM@X%z@@=S-t%!jY@Fx5~L`YDLIrxBk zD;;(_Rv=`<;Vkw?N&y|#X&5eivQj{wniM!qrNH?aaC1n_$>`8h&ktosoTf~|X<*C~ zKojYb@S``kbSF|g=Q4tNOJ4lrM9zwH?hQ@nS)Rmh9Hq`H5>bqFP>yj-dboV~OS|QC zF4{f)Kw2o*c|Njd(v8tLC!Ns;p#K+VHztupFTja7nWsX)k*5Qo;dxO}QHPSEJJWe8 z#Lk_C5Fc~-crGTWLKOqVTg~OrFAf<-pj-XY*#HL^KAfWIr;xg!U`sDpA<_=CNIv*S{#jh~>o!*gSHRb>KFMI#%8Wp*Ku3XT$o{(^|3k^J04UWF@nEaA8+ zKsF9T32?q*s!bW@(0|z8$1Jeb5Ko@Tw ziwQDf_*xZkTa6GY>k4$ka+Xv9DgSV8KpCW;3yF0e{Vgo2R+|DVL`_1%tZWe^gEzUT z<-CwN_j5rQ3CN4R)6sK8xt}lv<|CM$YOF%p7FatK^7~7e$r8<^tgwZt{fr>c;fIn= zOR8q>OdRUvJb3hWiiT0*3+`$ZoTwX@32A+4z~c@T2>a56LZ!-CO*(n01(kI!*0_Wk z))tIvp}cvytR)sLFyN3h9QC&{keRjL+`PxIJkP#xrzGx~0AfVdqcny%kZtgTD-dlp zI!E%EyQUSk-FPMvaV$aw8w{@LGzqkG8@4>`n|@gU8F1RE?@9KZbG}T1+1-Kt68CbJ z`{tro%=zoppat=oxEjBF(r|iy>YwF~RRXWrV~o(+jIt>&RQ!k^n6xHv3aZFcIcsrt zjPuv@)tokyvlhP?)`-j2WVqq;s}iL*P;vuk=7D(6aw+g4y4Vs+hr}$FRPN&hMCPe~ zKvI%ab(5LMRwS(-q^p6+KYdk79HteqnCx!w+>FnO7pkfX(-eOKbkQT1*!8V|v!$vv za0(Zaa+DG_tWAadZ2xE%5_IgJN+y5Sdk3ZvTbnFz=T9T{J7yGXPV`|WIzexZz_vUR z-hG#Yu-emwZ#O!LEI*9zJ81$^_UmN71PWhc0L&5&{ETj_MK%TX5ICTftWifgu7~y< zP!`OOkLETnfgGp5Z71Wwgbkj5lFxHp4)E-B0BV8VSyjTOs_|wv?nx^})ib1Wu};fs zDvWJpWaC(J$;>@1z}DS}adfiJk1}xysO_m(A#i-~?clktGOnD<)S9@(-n<6Vh`m1V zsQ?o7|HCMTc6*8s%kv*C6<*+?J$te<<_fbrPhf!M1f4n~GlKLuwT9nw#hi2zhoa3i zLkxkz@l#@BHn$bb2VRm2xHTbv*o=u{7%&|Je8F#!Kce)>p01p6$~eyJzNqb%)G% z3i4NRn>OCMITS+WK1uVGlBc!_z`v>vB7g}wGiL6e6+JY!+=}=3H ziAItWeX36-FO&BYX1>#I!Du0(OCp8}D{?W?H~4i=o@qy znb^FvID`qhU$po$#D2h%!vb}G6o6mV8Mw)#~;g|44RZ%`Rrhi%0O@5Z|odm zA&pO7%CMX!F=+#~6>Pz55y99p-M`Bfh`O?l>X%vbgnRN!AB-1LOjsZR_2%<|s@+LK z0F^U0bWni}6m1opTz`t~=G~XWcq{>l4(<`DM_ny0N027SC@wNdGJQEThGmOiN&X%k(dEV7 zxz;z6Cs97G0?aGEDWh-HV}3UPzH7+Ly>d9&D_a#i_X~I{)mia2R$HB>Ok*SRL9I0v zU~!$73F2VUJP@%x1#wQzmJloR#FqmEYFcPB1MwoWX#(iCe#&{a7Pk1ZkAzi1uF0Hv z@fd_KvgWmVlhf|8(J75%(GeVE!ov(c)xQJrQLSzR-{~l8j9ZujNadkJZ(dd{d=}=k5-Vo``@m`Go); zMsM?RrIaDGSN5meLgsCAWqHE zZ&A7EJ#V&RvmTmxh+*rMySnms=KX)ShN8ZNmN)9ZkY}P%PH7J;cT!FmFOCkINDS|Y zLN_2YvrpS%9TuSE{@!VHF)lo$fklE4^_g2!!l(GoZfiKxSM#H>(T}HeWoD1O3Ja#yVIb3N)B7rgMhBR@9p}{Mtn%G^_(nj-@ySy z(_MMjhXs1CGS}l01}QsY`Szc8|NfgY>Ni44l2|3FPkqH9&Aj^1&4Mjje`^dK;`+>$ zLu9tch*SMqHGC%US!zbJ?6|e?{82Txw-;4Eze(BYCLGzlZ;bf}pLyAh5!4p|Y%G;8 zg2uXN>vjtFvb$RTC5Q(*R_u|MlImfb42K4~p$Fu@^tAeN*!Z6)W7P=#L!OGeqD}X; zmyQ|nee#$5SatFV>#Ppix}wr!w1xKBa7)JhSTE7uyI$%0jr;Z^^fz)ulk+!UnlzCD zxZNf!a1%8h*gMse?+!~y2%uXvd;!1W>SMdw`RA2aJmjJObj(dH;VNqFg(1__mgBuL zpehrklRuz@p%wf7QZ?}cZxR8w;DMY0EWu)FArtJ#(B-P~%8R}fUvGLvF@l6Ba*669 zy^Oq&xdgGs{4ai)`^GeKE*Cff?f4ZZ5S`;`3U8fe-|_3WAqTYD^OL#$@v1ofwEI`4 zqPc2aO1xS>*o!qOeEP)QICO#^XE+Dbh2V!*0$`SwNcJ4QWN2prlP|#AhbWeN!8QUNfqNUd!D;vxWm>>ly8i@sGsJjpEF@I zxiPQ%L4ddK1A9*~#NYA1xST)VB8N+oqxof{xX1}TbA;cx#+h^h*|YG_X6-_X_Z$ns z07q2UIhWReZidmF9CI1;{>&zTT2_JnE1w8Bh7Ua$(=rRYEbvYlVcs;q7V2=bu%Ub|RJ>EFsFoODp_Rz^lV+lLaY(8Ci_!FuJJ2=uy4&v!Od%cz|yPDP~V^}R|f|T@IpbNuD;;mN*Gd<(524ZwGw0hC!g)$tt{Mi zJG~P`8Q0q-QN}}`=&}ry;=|enFT*<*ItC~^grmUUnq7Xpk@*N+M$)?ooC{}B;#>+> z$+>u?Dv2J|;4NCwh@~zA_m{t*4a0`OLJX!VxaLk%?!jAG(28Waw|p5edY=LTSTMQ* zvS4!0Dp|1ZWQ>WTxHd>hIs1GK9)mE<%ylXZa%+1ijI2hi|M_|%X!>0b?+C`7aEeyx z8u)?h|J`UW;TCPmd&)#&I+XF%y6%lJlqA=dH z5N?ry_VP?7xK&0xKj>Dqt=6NIIXOa;+07?AM*yAjTutDSFD5;NBTYr?wQpAD#|>rU zth#C7ed;(NpikJ8!J!wjakUm>5;&K!;e9}}!$L-(244Dx27w=KICC@KzV~aUgLWl+Ol>at{ z9FqR1Z zuAIIywA*T}fnmfip+2r#C~!r*cRZJp2tnBAKd`EC!Svg3uI-#ZA=;-QMkx>fJy=+t zb&F$LP!+p!>FXfi4XLYT(#f?kWaN{tl>L>&<4=8T>?>z3_jKiyD5afrR}_Em;61$6 z>d}&T2cIr9qbmn^&p%FCvs4J3lR#6-ahBP{NI9?~1GX{Ck)5g*Iy|}~0*(wr62dZA z7t+zEJS(*yV~N-|-|k7JeJdlX>Rc_SZ0T#t&~y4sYs|F!5C20P=UCEW`1V9^=g0xd z^pD_(YCh9t;Llg3!1v=iNG!2O9_9`(T~6^XsmH@RD>KyPaC)eIr;&@+_4k&|(t(}FD;#@l3_|i(snQO~vz~&N>d94g=U5@SFTzA)U1(=k z^+~EVyr{34nkPdY3DUpANe361B%MoCGWe`%A8q?1>$%w`t%7ti=qieteHLk)SYHS# zOtNGS=yHLV8gmqN@Zk5q)WNr!2*y7bKB?Kjng6sttjm*-W;=+W`U1_s#KnzG`UvC4 zLOxtv^(msf6Eo>JiSCG!hmkwhLIXU2*6+z1~`v*A}!@d=+k&Cdz-j0e5zKH&E~{P|gB|KTwoB zg(zgSe8N=;@aBp<%H8q3siaAt504#}PNJar{&7DD9*uUyN&Eqn~;KhoDgb;QGw{?$CBXJ-T+o&(`5IIZYA_4uFk0_&cB1G$% zx|_*cqX5`ojokoM!!of|lZ3{RNWuqv1bO-WBd5^&8%NnC3U_nAXr z+9bEb2Ju)lpUbBo9qNDmVww(K|Q^_IL1J>x4Alh=s+0&#gcxdxqfoT6Nr1hpSb}yZ#)|R z%(tcgSJSnQL~B-1>SP22j9Di` z+6SHL3yv=VTo#9(ttjdeB|x6`Heee33#{fZlK6ekW72hmo$1(xs8wn-q=5Y`mFMkNTC&>wbyNL9}t}+IME*P&&qy778 zJxG7{W=H64t`G(-qlIi*+wb37Ouz_EGsnm=5=*^qvR|0Q`jPWxv}wHUnflj-6RNNd$--NJOELxj%u2f0c;d4g!8m z9&HdkfS?6LT)+Uw4m`xzKS_+UshKDIBpP3pwh>a_f@1CQ5tU;4;Vj`< zQ2OLbAUchXjrJojy{Q=LP4jq)c0ayFNoF$EEWw% z!DiexErhWYA&Wqwj4Z0^jF6ebEBJL@e|s1N>fasS2;qG3J0Ta!dnvL#0N6Cnr^B@J z0;*U5+X-1w?EP~E=FbM{<=)%oUW2z>aCX+4AUWt!s3tK&1JJ732si`Tm8iZ*FH!AB z9=+?J^{}35^BkM0Cog(K{xPq6Y;TJMg8(-Mps=Q%klxQpd>=|JZV$lIUvk?W790T_ z2r6C@v9W*mb((*H!v>ZpiE^*QZ_@x|tyOmr;qJ3y7oU5$bBLvc%=d?2C;daXWyH5% zkNcK*aL^q%i<`dp3JE9hJ>!9x{nG-8r5s+OqucZt`0v6=Kenlvt(rc;%;|P2r%5#)z}h z*wa0p_miQgF;S9Hw-m+lA9MHqoK(F=N7?>~_JSkh%pLODD?%tk_rq6-vO zOdmVwaG4t*?r#mh_r4ur21Eu-P*PbB+wRuik$@ z{h`#q-?yg?5wfVA>PWMOQw>?P?_&A7Kxy(t1gjl|!IS?m0yC)_0jns3avkm!L^@}{ z`W>^m=6kz*dq)shbySN=6fH@`n0_6rrLJ0Py-9R~Cyd|P^q9f7!tB=7hmO6=E8xzs zr0A`Khgt$MbR<%Qh)E*wUjVusLVK-kZGG>|8g~Ak&bRO(bw)$WsG|1V@^?Z*C+fL}NYg-8uTo`K2;tr@g5rEZSMvnrRLCy_pd&EjE^8wC~9K zg@j9gA(KY@ON$$mQhnc;bZ@v~yF1-Ht!6#?DzlOXR>HqLU@Wa=^4|@r2fdKX{$b=uuSajvX zEX4O>P~S7ZoRQDUUdApK=`@9?Vs_Z@}mUZkg*0;Dd=94}h<^3w)0A!hovK63SFPQ!xy#@2se3z0ez1i3^-;;iX|u=V1rBP+t$ksllpWIBbFm9D1K!zw-^47 z#Y`CH4N!K0QV_873>`_%u*!DsYdrkhxkljjx)vY$07OP{XMpkBo6q_iZhoBC(3Wth z;Rx9+81-FAyZ;tb-)YAR98Pivsc(sn3A#fS*PFjUWyPZg?Tas-Qf(?yc{np7D2Je~ zRlemz4wSqJ9b`y^&4xZgF5S&7An0v-npfvPkf8;2*Wm%_pP~%I*LuL7{r)#Nft}q0 zeZ4VVZRNKP2)DB1Q8h4rpS?!3sY&VIu^YYdj-Us190MIkZ5%HAWj;tXXn%(f8tP4O z)GLY%8V>=b1VIs$W2rB1iF34Iw&_bCuJ`z0xrekNQkGKXotL^zc}S0ppm9Thi?V2a zeNK^HA9p6+B8V$I=~*))p?`}t_Noy}sx2$HS%Un1Df3Rwm>0^5`gc1OK-s#V#|UAH*W9ZWE#G_$R`B5OS-~*0 z0vacvk!TG*o;X(wc3<^x+5Lu>dC1_6_@dXIj9#myEd|j76o?6;)ZRAF;nZmEvO)vi z^Sg2espcE9jki4&rvO<968Ba3%gf@a3*{IrR$V$fpYYaVv616Ak( z_2x3FMXk>7bIXKPNe|+@TuISJ;MkqlV?bdqp$2gV=_;O!29qB#@11hf>Nw?MN?-5w zgFie8Of*UWFEsI&o^#BsXCcgiHBU-7qUM&CyTKIueW3G{y>Pk8PycnpBD7 zeB&SNRK$Hlznh*sg#TKsqe&}4?(vzU6eV~rYPSaYRQYv3dRGfsCDS*|>nq!Un-pFR zZ`>CPe*}#+xrz9^=xORU@v$a+y;d@81gk#mRDSbaK;Uq6bpirva~@}!oo-rLI?fwu z08?=^FlqCP)^{zyT&ciTbkM(xteQ!Io8N~lYBI zit`S@3ld7$%97Xgm~YZucoar`!6@j)Y9D1`a~|^E##-J0za9P7@zc1!5qG7`Ai`4jg0{T!RFV_0qXJ@R=^LqCVWWn1_mFU4& zUxAdTrvmLKc566oG2{LvjsVz8-^Q}D` z`J1|;IG4_faigZ^G(B})B-Cs5G~9;Qz@k-j!qFN`0c#3&j0ZoE^BguS%Lde$gvMP|J# zL#$Gsu}715%l+v9B8(b^U4*YAUk3djrs7+L=V8nWSJwg%<*5G+ROnVJ#>Cre}idlO9vxelIl+3>jN7oXQz4^LO_^xd-Y8$;rYgHVdVDX-I-0(?iw&> zgL-tjAg%o9DkBzl4&D~5tpSVL`ucWYu%z!|`w6rIBRFyoct*ZoeP_xECr}0uDlqgv zn9vb3Ry#*BZ_3k32V-EEnIVl^98VussSu#l zSKpxH2Db(+YHOtbUARalOV2Fb`Z^rySx<+XrNffK@&NzJp}*lvhr!k5HoKb?9=P0@ zeTsD3#)X4rUq_UgE)j?YnUYxs+dHd+w3#;{6<`_baV6e#hj|8Wd9WG~02#ePPU!II z(L-hKV2(n7L`%H^@?9E`Ri_Q6w_hESYl%*s1z~`Gn1gYn#+LlIAN|X!eRQ(qqrvzD z0GJa~4C;y}gS_W;LgV9_T>)tjG$AmzN~vH1tq2|1H4rPP^aG?0)JdWV(b5z2Xg2Au z4w4V-dR=;c4gTPudW>-U-pQc!=X*oqH#!pmRSTeEaY&MS<2%&r5(k1z`{G=UB5a_dM}b~>9}Q46EFnFZp683 zz`Mbkl- z$#($t2OvlS6|n!mvr>c*8$b<%;B^7UlkI4T;DlL!Pxcl= zUe4-E{ir%n*HE8(6#46lF>GBeW6=Lx4ztL_PB~R>(adC=1e`pNO-QC-Vbbdye& zU~9Ks{yvgg<<_(}M(9&jc-Z_u(lmWAq0GA`8@&dVL$%tZ z-Fe*yYNX8}^Y()2@1{uR80Jtt2U=9YPw)LqWhSoNPvp=$f0R?4`k_5^e_faZrgT1? z$LT(I9X`3x+UeDHN1$16559Bu`D%TqAtG^r0!m_yWdR&tW@0Ib_+%gcC+01w9ciFU zdP|CaB50j?SZ@^qjF&Jk|DWhU{#(AQzv_&10TYo;NcVvx-gJYgpA@3mo0iEKOe<** z$(x#z_H?PF72|FKtrh4Ry?cv{Y^v&DmYF;U27Q%Il9(0^0S`_bbt^&F!XPMYu2A0n znbPimqKYu90uljsQ$>Ia(zivo`y{by_HMz+ki_!7Oafx-GSWlwD!R-K1T#kbG;J^w zS2lgjYcT^8v_p_UtjPR)5#nIaEbI>ontA+>w02j}eSn1KElL>w#wYl{Op@-`#qO&6`n>*uEH2R8ua^K+MtykXN<qq>5Vh1416vPOFRic=54OZ-oBq^E4ei=!K?aldl5{YNj?!6Pn0I zvtA0q4!>v`wJ&I@nItRFdnuUL2udtrNQDOEo-JG4q$#&_iLep@pYEw7umeFElcSFFAvF?Odq4R*->p6^mB6Dd-Nz|GICLNix{#(Vh zCI|DY^csJ6c^sn+{%@;`i`w}Jz6oYev?(JNdiW=ZAI6X;nJ4;zx%QCgqt{OiF&-M> zDwRI#acBS8!TwQV&S0+dtvMHMN(Vh95!-x!ii9)w_D;oW{~U`6bRyQUe^(4F4~c2@7^~pXH1-%-iYs7sQQM0{9<^tOXH7KoqQJ^ zk#%nYjxCF=!hdE_szoO-U)i{tGusv<6XgQr|INGkzc{JKfL+mK#ug)s9jp|tIa~T& zTAk4?Z@-rIkkJ)47{_@^=AFW%q^sY^fW=6GSW|BWHpJbM(V;e zp`aS!Dwt#?J7OG1nI)J;=Z6!-52ZZQOsS5&<(yqFhh;jg4_ovTY!lXo3f9)1iBR`r zfQ=!CyxkaWN|UR2)^{*cy+lU4(UZYf5Pot@1uQ4k(d%F5a-Sebo<*XP4`naxc*7pc zDcG0jeUFiEuzJk%AL*SwNS_n$%!CX)Tfb;P(wIL<%r+*g<1KX}@Hnca$&w z2)##j+EMPWd>!*)JgOfVXu<4;D4-SA0A}4v^Yu5jIP$^1xN8P5DxLfs_eNNE(+GY0 zd$EomND8QUVVc_(i!G{{zNWPo5{DXU`~KWN{eUJweE0@KkLlB*dQhFn<~69`!XgI{ zm`EH_1Ssx_Fn(KXJ{&eRPbBm5X2;#(^}RRszbM=0r`U6KgBCb{Gbx;Z?He}GW^qQ( zM7i!oIRtQrTim?8y{q|<1Bs69#xGux3%dtnX&@fMPts#lqp%zzc8_r-O$3x&W*^8` zJ}SHZ>KA)+_WqHOwg zWdjCv7f2LLwrb&^CD=f@;tec^@vX395_aL6_3vUe-ys8bs-ME4(~Y1b4gCAtc!k^i zyw)Ql$b^f}8BG7a zhBr61D-9y(4;Mg8dx1s1lMb4 zdmVsAnpj%mL9IrhqvBF&67zKkP|DE_E~xW9b`iMe^7stw^YDYR{b`f_gt0y64;2FL zY0@@u|JIQ&rdpwY-v>~!dXqY}$GE_0(WT(DTEeFNhHjfC1XVDV?rIfac{xo$J54=SMj_VgXGm`@ zF{nyF4-cr~8dcetEWJe7E-(PeeImhx_c%PjhuMO{`WcKp%E)eTnYn2f4>FAPT_^^* zavP9h=oEeZ&$?^XDBrl0^<53OwS0_k9Gq24AXZKwJ74Xvir7N1Xi6~KfKBl2KwSEQ zSX!sq2wFtDKVOC~bKyAyU3cwV><3+2t2oY63SoJ`_4u%W^ib^^vUjcSualP}j7GdO z2VNdrC)qQb|8vhKz@F^}9cept7q>1v!m|<_jqxTZ;AkwRV_M}CC61BQyt>&aSK)&h z2Sd1M6w!qA_DdNvfLKIwyk6C&eeKW(===+mt0s^rM=W5qPe|#X%j(340(hNvi9q|Z zztg?ePYgtq$_+d1b8*${T#hSQZz9GX9K136y1_)xyVcPI+@({d;@a>U%1fE=DVRw= zi?G1;cZ#f=Lz!y*_Kj8Bsvx4_!7?+;rW)n>CtsPKs{3k9*1@rCPl%1*W$DX9Pw7Fx z)B3(tvqU(~?U(qWD?0lE3`49=dx&3bROklp5GGbeXSUpuc@jTE@azG8I{RZ>t^mko zI2fy0p|_f*dG{7Q9#uOB*PDEWHDKwLpp{%a@V;?Uc*wPtgtgy8sHr9c+_!9-*kaKQ z`R@40Ge`FBuUMLi#W~T%K#Au-X-V@s;A_6>{`{iD;7AJOtUI$M?-C@I7GPv$w}qe? zrPjp&q5%co4Xz4fwYR^+2^(-u#^RsX!tSMBe*RfFdp+ZZitIAKU^!%(c?N@VQs0%o ze^YP6fyvSSEwpc3xXIn|%vd<~=fxaX(Zzo2{g;Y zb5wZL*!XsRM!^y0Y|KiwYcR7nFqt@T{@DNp%$VM+*oviZkJxr%5aHT%P~iRaQ}r|V zXTW|-BMAeW_TpCE-1Bu>d#jdGs_cy?_Q#@+Nl4x4G1L-de+8*bi6DeJ5CcLN3rcM% zkmQ=JoaqmEZYuj^_eVFq=(S%he=Y#B0Xg0rEfBzAooH+}d>I{Zv#8YjIQ5R`(Pw8RYvs%*d9J6IUtvIFL&>ydnV0A1gal!zu40Km^Wc0MfnR zk6QSqSDpvCoAO<00dS0HPkvQrH<=cW=NL~2x_rli82z<^ws{&q=ELaAXjc0dC0;uM zE*xkq=LdwOFALd;AS2BPf#q|l{@Ep`w-P4MgB$UujkWT7xQ%w?XJJ6(XixcMnHTT1 za_G3V@s^;mHTa9HVnt%zt&cw1YGHQxhm*KE-nD(@L5qvQ!BeT}Mq{y&&e-p7 zan^Z8W~5$E+!u~N$fL_)r^BDI(?d77kYCIARDUWTFX^rm;+7I|8gf8cMrI*^33T0T z!NWLdqbz*0HW3mvyjU@8O=WXilCkaN&*exjtL3qoQVGgO?|2Iq-)8Tkx1xqvBCa>_zIh$-3b2`E8@5o{9vM}G*AK%z#;Z)}kDr;_m5(j~ zpwQEhucvwl5tgJncMnhQH($>=7!%EC^MnBl;Z~Qy7wrJmOauWxmIaA?H37ged)c-F z-(5154|jh`vlL8@>+)sa>u6%-2)L98j%z$t*m@rS*K9p= zZ`{E^bf$PskE^KDwWYl4M<;DIN<56(jX3u!bv`_J+wEslWPvRu%7$FW3nL3zT6Syj z!QWl~(MRdt*OzLa0kVE`Ubh#>8on|m*Uk>>SCRMwHk9ZA8%*RvY{s3jL&;zBYXg2U znSUB9o37B!k5u_0LLSpP&Gf;6in4#>y#bXF&eTSD!q_fCiOLt}-rTo&Q|HCtrZ4O* z{T=N@QQsG$oL={@d~$8<1PE#Mn)T!4UmQ}9LLa}t0(n#Zb&Z(<`nj}(0a+c1 zD#M{1`H?GYl}ktDx(p33RYw(I{`FLa9>)^y!>Wy3&&bsPWO#BO{JLk-K-dB9vGnDipOd!#x3Ty)^N^NxwsB)x;Jwg zv%IN$e`vjS`u^9;4P4qhowwjH9w@5viZa&kl3OTm^4hty4IJOsSX11Q8yr^*y&dVMCI;oM8JHe4Io|6CMX>DO`-K& znEuVXHuhd@XdhDs{-%y;=wL>PRK*M;N@_1G;E8y%5fU^fUXu zc01V&8p3e%?l`?*T1Jdvb}EpfUKdjv*}(i~>gmCV5fE8G;6VZ+Y;dDm%z;QRacwMh zd0KAyxUzUU!j1w2Fqzpl#JZ0TnX(}1+g&~nt@ip%BsXbQRTwJWkug(G^FN_Gbb~h) z++ftGi9$DhMff5_Kx4R^ee_UG=CGmL|Hs>R2Q+%6YZ7Pw77^h1F!$ zMME|?UAMD<0MwwztF`MlnV?Jj*|b^U|5D+f8B;mBm#UuYXY8dN;lUjQK8~{`pnBbF zf|r5^)o&4d3HqlNhV0t!_nEj`*zb<|0Bwej@3DwAKlRl9EdTVbg3y7e=QC3qBzxq7 zv+N-+=GOt}z}!nT;%52Uug(vjCv73@=7Sfluh4nuD))83(7m3avXP$@GvGCmhU6<> zS!`n9)`gK~51VX|wheQ2^qqM09a*lMW9TZk+0&$^W_WDwBVJg*M znzvL;f?bz8Ib>ny=g{@tltgfEz5scHz%(?9Z&4NYw-t9H6lGd>4EdB)|BYzi4+Cm+EemiFJ>zj z)Kfg#Jk(5V(P6!#&EuCA@iE7)I0HqB8z3+CKcw*zau@6R>U;Ovs34@2o$uu*gJt81 z*19UfpGZ?x5PSsspD*M>H|>sFh!MDN?J5k~-YYQ;oG<7P*TYj~^prJj@02Utq!HwT zx~4msuN0}OBRj_YFkXK03Vg0sK`&3PwX$Euzdba=rDo#wFuFvJkpceSUe1N%?ZV(l zQ5a4&`fGG_anFpB(l!1z1rQfA$}qeqW=B@#d_8b}nx2K0piAF98?OMeJ$Bc{m>qgu{cjcUHW9k> z?~6;)gXB=YHL~mI!75u4ZOMiz8TR7}5s$12u7_Vt?Qv+2y7GR@y__^N#fjsPC9K~P zk8D2}P9oKPb)kG;hmgmxw|!}+uUeIs19@p?!p>7Jm=4o{Mf*qEgY;w0iY5=Y8d{v% zcjV?z^jo!uRgOLgFPczuWOE|=dkNVZ?$H6r^ z$@4E;$iczA=?bb6yG5~hbAbbo^xlNd!y(W#Gb$*g-pyEVnwEeuRVx{CI(ZavJS{u< zyu4mE5hl${mGsjJ5B5GyJV*Fz^O`}@{Mz(aBf*CS-%Ak+eu4=`K7Vv01V+Dd_^T#G z0Hr`qK=lL&OH}552ah<}UhNT?Y$II6FO~TlXI0lJx#fLeLr6?hyCKY0mk4Q3yETX% zS@7%1v{Uyr=1ap28*9J4>Kl^mCkOn?%xlE6Wr-#yy}$9ON)zgj&qM~>VrE(}PT`j? z+K|T)!cjycgip}qYcijX)xX@2QH!8+CyV>tezAN84wcV(dNr`^iZR)6&JE7@I*9gw5Sz>mBS z!ES9+Yl{$E;wRr-K;4O6zEU;3={h?L2Iop^LcKr8a8y?$!_i;?F9+ExzAPUs$LEQr zPg#>~BXBb=^8hdy!mh|UzIzH7lN)+fCGf!VQ-RNH<6Ziix`$fKB4?&btE{mh<8Gmgt}(eA{1zP}vY#kk1W(NmXh?=u3j06VWy zqn*s8y}lHCaGQ^bo7rT(aNQw%STNC0GuhCw@Z6#%I}K*VE_3(S&8z!TIpTeYe8%qN z(gY>Qx!3E9O74LXT5BX-tS<5elgO06WkZoSVM@s~U4b8SgkR(^x$iI6t})$}{>&Mx z1QOHEL-#J>#dEHpNs;qx*kpgid`M6IQE`c@vf-%{5AeP^tRJ?>ZDxFo)7hk~M1pcu zJ?&fRa$!8KR_ig{ENrlz&bxU-%gC#jc9Qo3JKIO%Bnaql2|)5&jckIAc}bT*t%=DO zB{q<2^7__ndr7yM4-Ygo+y;(yC7gaVfC0 zG9P5jTA+Pd-6g~#t?)|%FBM>i+!Ugacu99_O+rt#kbSQUGOBM9lbg9s!|-oQ_hfHa zr^KweQmMD@Twd+O+i8%STqO8~%3r+_!fE4KNZ9Z!c2Z|w2J2>t5I&)~|0d&G;a}?# zrY?Nvx^z}IqB8^*KsO>q1~acB`5$*#+28t6KSq26GNb$8w6m&VrYL&O*OsE@;hvo+ z{X>Fh%ki$Fz?`x%+!n)y+S|&Q(Qp^}iI0h;8sBfq9XZZUPU*uGGG?#(%oJAH$#upC zqk`e?eXoycr8n0M_W;qED-T-9o~^o>W_9Y|a=)LUCx^CINlVuU94g*aZP&_Zs;Tpy z3uS+=6RUv^){uzvADs8EGMw+t%b8#^7xv51aOc@(>%Au~2e$0dxe$59_p6<=vl8H>axv3>o$(uLb-?IO1;l*I((}!|B_FyLyS^svGGpV ztsvvu(i0ovvaasczC>Av?#NKc?R|aEx{O2{p5i+Aku|jPTZ`?7F)zblij?(@+`}2d z9iakWY51j~2@@Y2M+_Ase!`IYv0&uQZ3qNn1*uwD^gv`hvCYSx`R`xn>n?b{uvR^2 zKU@CU#augE@p~g%{n;*ZU1UYK1_?5-#+BF}7(6^)Gzc4K*9bv5IPYg1NoVKfG)YX= zFrLE_u=53Y^LzNo)7is4^#XUD7u7&j!mzi!>7F|g`|=~(y<$o?$TM`@`C)KP|J`nt zG*`Jp^W~RdHb+ha%msDaJCcGP{jQ%AIesnF4n~L%TRZYX7xy?Az(New`0x0d6jl7< zIl+O@p@_9@Gs0V)Xdi)o`D6pVwP)&BhWfgp-8M@rm>(4s@8zkd1;Ak0n&7|J8;VfR86bSKViOk_bGxwYxN zSK3I$wbe6`@}V@s8X1fmC<=zLx_bQhQuuV_{Tc@Q)q1^`GFhA8#PK<|>SL$*(nF z$V?CXo6T}P;m7*+t}`ep@5-KQt2C<;m#dsN(BOxxZ8S@qeN4Mx%kBva2#AMCPzuU# zd#vOf ztV^`s=v1bpka*18+NLKvQe>UFZorsP1T1XLd%kgzJsJ*#aLP5TN#orxYm>6BY724+ zFw5HSTK!ku?_AUF!D8D9c7D_+U0!#+C*PmSrYn`AzQP-P%4NS!y1FikX*2#BtbwSfa z9=QVS2e%pddxq^qlN}e9-T~Cb?_P!b!E(JA_sIDTLDDw{x!onoB^85H+rO@Rc)@U| z`$?}kv-rO;fVn&E?)Wtc9nh^(0g$UV`*CRwqQ7ktJkuT_^v~-ai9g6tIJc<6I9$GC zdKX#~?}WB;(^-NCIEG~&-t^gd@|`c*J8u5Hju^@Ed$;SxR#xF%+V&JTkpS6>|=8^LeYM37%1%-~GWI$*7uEGII!%RtQyV%s*SybXa_8pYz_f?mbK%CM6xL!q467rDEpBkBPPSbr z8+5DNeSx=#5=Q*k9yxV-PT-rgn69C7)mu=wt!N59bxyNCI$L|_fN)duV9`W3^;Q=B z!&}Ek(IxjaZb?c~Pg4x{BTJoxX-xetCErI!F`KYFzEkuV;g!4tUs^c7_wIIv zny8QVMV-O5j+fD|SJ{obB}{q8MKoOHFztFWyACFp5crb1Fy>P+*fgKW7@d~!QcbLvdmYuf zUkSC*_2a&MjSuT1zwfx&&Nrq6XIRhdS^fd-hnf+03>z1Y@TXY%tcPvjAI!7`?kW#i z3-1WrQ>bR6h9xaLpO_b0vu0^YkA0x-SBd4x1o6^6j+SZFYZ}R~j>c!5Pwx5pj_1X_ zYwy(`J{bGewa<2aGrDE3(T}%H?jAk7!S2}`#O9ZZS-5j|Kl|$Rtr+nKXBKvJCYZmw z*7c3-)@?J6246E3K7aGoH|5WEJMxqQwYmnoP!@QzL3HaovmSN73VP-=k?xns_25<# zGEA%(N)BRxenYjtnA-X^}{xvW&?=-He zgV4liz=3H8&1ARqp>aTyz;5XF#Xu?054sa6Q5thQpuU3$_URDMk}cgyr5L6ZHm|QsH(>sqa}2@X9;bJg;JzzT$F_BF zI6-JX^Rz+7;9^9ltXt{x+G_VE0KSaOij!x=1;fqn1{;!5=*wDxKO}e@L9&XSrs5tu z<*1<{cLi!(nnaf-eUIZTEpVLc^f+39^(MAbi(IBxxD#@=r97wh5zpMI?C^kmnw7|E zXeVOAXno|N#SRtTNX!GE$$ek6Cmjv<*CPb2{98=Fd08s-B z>-%yRCh)=u5oe^2pDU#0HuhkqdNhc0&~w%0WMyZkY#6Z<3H@l@%Y|k`l4$J&CqFGa zzohe|u7O=G#YldwcN7jjp5S8_f{jb4h_oP|s8N=pKh8W8S8~dQoO04LbprA&g}(Cz z(Nf`fl*PDqk7075POM?eXxCy3`#BYIkd~29>X|qGV)RM0$U}TFZ9<>b91c4^%V0y` zVjC`8cdDGp+Gfw(wwFg|6+Z@agNjCoRB)#miq{t%1)H)4UPZa&l%?s=En73}7GFzX zUUD5AN&Q(_S&x$qBcq{~5VZ#@=!w&?e6NL&o=V}IB%3H$B}P~z=CpE={R<&m&p8WE znxP9E(Q>)OBJH30P!0(m*-n3bhsv1phQcau_Qu*AS$JI8x$n_Z)c~-%5OXyE0Lj*X zfn@mDQI8c%bs>(q(Bf_^Fd-xzym2}y{sQ1NJwFS`CdkpM5mQg-3fN^=gId0Es4Bp) z*mCp>@LM{6{Vk4(Ib+i|y>a!38}Rf+5rqa~yW~v-MN@i9#5WurJJpR0JG?~1X`n*8 ziDyE_&XPplctj-kdvt+`$G+SapPWboq~FoV__vv?1iF3`L=Npm>LmDNKC_^==`&+QHPa&AtJ{)_W(3%W@T@CGw&hCuB|{Yl z6>9qz30s#yu^BI5K^{i~pp7Hj>;09Y4mf0kpAOlOU-{DtU>Vs$le;!N69sI6WuPye|X3g!{=3Uj!bw4h>%UJZ>y`b@3-^H5l12G{hv=7hS z=A<4lFWRbMMiTYhQF!GT5iVxODYxj&cQA@U^<#6{Y_>=HDXAx#mBZrH`znE#A<(G{ zrX9F&bFmo3E2fpT%!er8g>wW$nUeyk=EXY-VcvHGl28OmC4|Bkt%aUGRTGje-Lh~d zAIj3Z-bFM-MW1QL`;!7X0Df?iY0Rr=cTVu2uF##S?+hQ(yrLS8cbbm}O{WA+^cAUb z_it;_KPs1gxH}7B1KiL>*uovyet?};+m8_8d8lfpY_$kPKFfrNCVO$`Z3i8l!ossH zTJ`bWhl|9KHi;iy#`Z`ci3z85T;t&G$dc-X&}!+M?xjr0@L4LAddC%)Sj*oo&MU>Y z(rC`4eO={F!df&oso2tF54rE-5jR=7nn|omHlevcsR(77RMs&EIqpJd>H;|{YWe0Q zpSMbUC%+uY+eGm?JUH5gx9{(>XGM3aFpxC&d~vKka%b%K{lYEhQ3dVwkr?+EoQd)l z*6jtrCA#QFTpXJf(H%dmm3V=(gc>&MmFe5Viy%^w1JH)DWzd3#P>I}gVt~SNlH8(; zLn-WTO(_dlxPiav4So>4Gb^IOxM{}WxPm%%M0dm^#uW!wNJ1IQAgmk{Jnpa1R#|l} z{Qb%y7`H8WpPQ~L#WC7(vGX!={f~aM=`id$(pyP^Z!S$A4)w;rM4Q-T!M z#=`S#i{oDq9dK&lmV|xg(^iJy>A3#apN^xaTuE!3`xo9~kjMURN;if+rO(n3`jET{ zStUc(7}9x-Yax^5Jw2VYsESJ1ml{_uZwK*wG*JDT2Y$9#4jO;vL59M;#-#@JJNfm9 zetT)RFAt!1Ox-?=aJInyoED|PC8|$|;ZS2`P0G!K?gtu+ISU|Spg*=f&-WZ}snDw& zKJPsiiFWxi>+%yX=Py%>f6_p0Y+iv_eNTpy83J+fPI}!#RXGScZZbn_PAM0P{h~9~ z@$EmBW@}C*L z?Y#>v*j19IRm5o>kc}KLjFig`)AgPC!5k97$}cRuaPi{Bz8!j(Gc}s=z{vOUF`h!k z_D3eKPg3$sOux>B-iYON<4Kw%l!uIpe3iQ1E=H^RrBdJOl-bL85mP~?LS6Q)`Tb0! z!`+KQNO)E#27Jr6K>>t%&JIb8Rp2NZB(I$-E~&~M;1D@VAd{RJl{!~;DsBu>2^JVN zpPlfg`#{f1MR^LX9-;jmay_uMKiE;K)7}(Y*%7FUn2s?Rf5<2uN2uM&Kh+H5MW^5D zdFoYe6q;tpdgDbJH?eXggPYEM05ZrXO=DOFs{71x{?)!;2{HC?`Neb+y^HnwO-1Oa zzk#)ZGBYcX7qkU>QVb(**$gfq74}c9NoAfsB@?6I4|WwC;2JR~mhN1;zoKpkke0go~W zpnu|z>#zpX7CnIgS`0)ktOHqNr%eLmx^1C%Vp+Fiar(THMMzpCNMS_b_D`M6u5i5f z-Hy$`_~Sx~yI)caI5>;f69-hnTeQg_n7;M~`M?u!_CEK#3^Lda-+@%)op#TxgK6r- zwZtCc>{#!e>+TnD#`r)W8dmq9kKJcsXDOJ^PKtc+PS7GfD;WdwGSyNg<~%_$Tyr| zfuLjgEtLALOpN;dlW@H{X~J{vW4rK~47|d7Dx-U9sHy_45xE{pE~@dRjMhpitBArS zsL*j8`psIe;9W${(_h^Y6BDZm#~-6W+J9pG@3?3B#}GG9vJ`ONvaFnrcVI}Rz>dkU z|KE$qKU19jK}dA$%pER3UkM$qM`XouEaA*pk{Wi*j|`IV6PcHwgV*42n|oSs#{<@wXIOXguJ+_lCEtU{yD zj0wQ+H|KBQ#bEVMy$UNynn)f@bq7W0fH{B$BBKEmI+e4n%21OW=*i~Cd$vsE!ddTB zp^1E6>p1&|C81!iu*ed)=2?u8v!KnaUhU1?!OnE0j6;3xkD=p*V}MBJ2RcnIR_Hz* z9K3Mn8R->CRTfQA9w`)>QB{%TWAC$aqGu)0nE>KMvnDHyTLdopW|*GN;cv@2ytESfQ^{$_fc_IwV-*tnA46sv!xF5G3IiRs&LR{L9|j_JdC zYKR^9Wn*!E^*nQwuu~Qu>c;)deXyiSx#GrfGhVCJ_tZH2#B!+F`(v7@_C#tyMX8~i zh>V#Kj{;97C<&r?sprS7LD>p2Op&4H@0X>2@aH|Muc*m<>kdyaGdZ3LX|qPz9}ZRu zLR;TrIX-pVyrq!)`SQtVx_~o*p7zvF53k57Zv`LTyq_8R!JD5XX#0HOcV%jp2o5E3 z{CAOp6qR3hHw>jniilIR%yH<`HzYtu5+a10syTh9# ztCnxUCYz`Dh zefH21TIHV!8A<`RjFLlZqOMg@n^riA{;qly?_ek8JQwB3S0C=gnpEcA`YZ!#l_ zr3BIt0PTR2KnpYi_*K&<+veZLr~WW?=ihC5vPK6#1nuHEQ4&7$PG58mHBgF@Y6%d;aF!GTVGkZ66JgqD zAXFF3UV~CpEi!~ocr1Iy{>P4r(1(fAawf^-`@Xe+fB2J{GGY$;dE|Gb$(}o6>({NL zh2y0!+1c5BjD^dxT`xA{!)G@=(7C6u`~Y73Z1rM3NF_=u``eQZ*RKnbg&!#m;7s3f z9b3GnN(A!AqFmE?V6p=hHykT-?I)==QDS4=4RYVrIyEos8v-Z_^S;T=cwbjiD%t7y z7cDE6(m+7aA8dsxttX^yA*5l4yP{_Wyu;3OU0u?O<3`Et;YDhsq};Yi)Va>e$49p)v=0 zP0Rkw%*?BGeI+RS5Ud+N?8yt6k9{S4(!R)!G1sq1t9Bj{(-s2^g=nbjk)h)IdShcp zhbi0l;Zp2|u2%x8L!ygUFLrxl_$Cj8-<}JZ&NTFX`hGa94UF*`cB2L9UdSpR=OizZY1ke)& zcFGuJ=VJ7hW`Hg&+bRDx-Tefi{ysdx#OykD^BLS1U?enVj%@`LCV<050QSaL65EHZ z)H&xTYdIb`o&iwy zRg5G%*mUsRJGi>K{_x6?zv)do_NXyS!A@;r5}y+XZ}A~#)UOA-@be0^TmPW0H4yxi zhET)OLS^Az>g!-WgM45`ma%p;P{LoG9|pRlt*aNh3+!tEgW%t=h3K*Vy)ibX^9(Y% zbi7rUG2lUEYin=wi$5zZ_#gsvAZrul}oOsl11LKnHm8dX&!YKdsY5^Q%nX+ee{ z+ZG@Kq}%%ImD`MAQ_A5@Iv&?wVz?x{G7tjc@f1;@bx30ZxehZ(SQQ$o5x(Co_a!=j z6gPAMA}t#npAT%MG=^uByMt5arA_7cAmflKO9tI%c!h7y#+9VrM@NC6oEEu%Rk{nJ(rxqjewUGV z1&gZhy3WC?fgPPy4)rqtY64bJ2Vfh-r9}=v5dI6T<77~_flk-|!#ezzJ^A&eDLP;X z5^iJ@;fZ2y^>dw>xnND=<@r9}*FcQtY`j2H-5OV#Kjo-v0M^-xyP7HPr~Xg_b-&Ap z_`Jd*D6Nxq6MptK#i%-*;ye`Eo0|%l9ZKt0@2&dBl3GS+koX~p{xVO;JRuG7>QT;K!oT zp{hP3L|sZW=w25)E=~5A9v4Shsrn8pc&0mBQzIQ=@4Bw$qJ233X44AFOZ4MA>R! ze~B?tE=!ptSHp{(5}QG58YEl>t5^*9R*yVFwXgXJ>&%bG3KzR#^}uDN*dGgi2ndwQ zaq#D6Y8c_iNTJhY>gcr|9hq;{$bdps`4>~bWeUvi*KYvD{S8*`U->KgL~W#_Zlq#u z6@ID0(sZ)Df2fy*4vg~Z?bWXtg4g!rjWX(>!(C$&ym?nf3*XY#)^+G1)?Pca02}0I z`r!Dc4v%cxw7-@b|6kTclp?hpG>mfLyuL0s=p7rdUe{b6bkww z&&TS>eF=-IA&LR0DP)ZJvoku}cYfwpIYs2viyFVS5PK{^de{ba_f^4o$guoP*V24W zx9s%$ykyYCKEAhj@LflcqbdVF<$^5R4*&mfD&)YaP(xVjW!v}(#6cSc2|lRD4mCfC zNBYji7GxFLxY#3CtxF8?v3fvbr^~|L)^*`gOy#xNjbktCLTJ|A@knRkxlFTpp_jF0 z-x^#rK^R-$dkzHm$kp2>01iP(6QG}8l>JR!;=tcHe%NC-xW|qym-?*S$|urzd-zUC$S8E4bQF+RHVP+USO7#debkbtMi#p1<+~#6(I^m^BzrFn(b@h zm(4#>Q89`n+iH*&9=`5%M8>_a6niix3jp?rRXkb$NE_bltfRj7o*p>9oe6=A8}0cW zc@)y7bDoPO5FK*C!hUqHM>7v;5-7@QTXcdF>nGIJ-Xw996YqL8u4X+ z$#wE}kU&4u5Pw$6X@!P5@`0|V$@KBgtXH>Oz$ScLraP`iJ3!Q+O0I7Oz>q!EI|lz- zkZQSHOAMEa9pG=EIq_}W>$XvReu$64|{9n zs=1E0Do<;+&%5To(e{}>)czTegPe>zX5_ftD6RlI;_3Ld&AS@pQKhT5I=?>I5bH6p zGg;2ut&F-|ch`#ox5}Lx#lN=7arknX3;U-DGujito!4HfQ;i*=J^exh&h9iL`1QUk zPGv&VFamTHyW5%=$4zQRI9+%Bsc#PQ8TrHW+@sH7YoJ%kY~VBi2fn5>qJx0 zyytt(Z2Jr92yN;oI#|vM)4^`Jx@Oy;*O>r7J`kS6VE2Qzbe27>V{2PYj>$8UiS^+l!mVR5bgag@BxA(!QhiW3!Lfut8u0c1YmF{L>05$D;LJopjne}#aa&G(W=qK(Q$6&=}`f~LTWqlnoZw6 zXEp4VkST&CI5Y1FU1xIR%)vJ~tlBp*cffs+hD{IOqzyOX4z=^knCceMq(uKaL;m_+ zGKt*v*KV+<(sV^P&0ZrT%8m@J(W%w>9xH2W#b61Tob*iU(7I7+zY|Rl*AS?UGKXx{ zuxZqG%!})RV1fFV56+E?3RMUT5D_1ztU^RY&busR;fL#6XJACKF>A&VaH0kclkIB<@}k1c)tRSTdE zAf$~@Z}Cb106OdoI?v#b7=xo;1g60t#`6k4asOm`R(zo4FOvQqIqz!Y+P~(f0<4e; zTgt0V-N>2jRh^#No{y2!GA_6ZLiKiIh1ULtG{9Lq1ICp^tWnYM%0IIR=%oFR(_a5f zi1HP4a&T~4rqfb>U-8ilZcA#I1b&WQl zZa{j=nztRg7U@K6_f6Rq-XxlTTOMQj^BmD%aVUt&etct2vl`HxNk%tAVHv=I+0OH@ z6Jk#1wZchtI+VvdY!J{#JcCmb+XIuCr!`k_TVm`neqhdd9D8zX9gxWM8^G%U!q~xlBCVhs**Dgj1tOeB&&3KKhB5=gsbE+=)WMDK_!iXb zQJ*DioFu)4$8^3sBi8}#oYo5M93TOSt>3(96PTtr^0KnBvP~5`*?(L2D*l~5VRABd zxQW<&&oN6{TntwN2ddFUQRnajEsKFZM-sgQ@Z%KMx0ENpmOdC&iN85A`(w2HTIIWnF3~R*S?oxG@;Azb#R(+^Xqllq z$}-=E&ba!*X|2s>7FYRzJnYKS#YC3xdOnd{1N@`_yLJCf-^F zQlv*JX9-#7w>0CMlmje}Po+y0_J{0nQ=bAG*mHR7I{3UIFmjOA>_ha4 zgF)vBasykbj|<~u4)N19G1~{{HeBIp43%)-?DlHJ?QuNhs-#IAYrLgH(3V+8TYQL|C_}(Ge!7Cy{l7l;XGXLD0R|+} zgf;`3xW$wTVu)AykX>MNB+~{}y!Pa*(wruuVr$1OoH?;S{YW_o&tI)9?D5Z>5NT6A zt5|J{nOTqh-dElW^sOz&{gcJN2C3GL5NFC4IFo`FpXATqp2g{%5J_mSFjs1sm3wy_ z2u!^OqpnZrNZD^8eQJkcAXIgYdP4Dt;WwY3g2n2SkammRLPUldx)ze7S*fS$UxCdO z_mFWwsMEKZcO5EA1or}f&$E!W_2m0JeQ)KgM$NOy_v_`aI@z#VN}vf`?t_(_8T!An zp+UaUb}iv^4&Sn~QrB4Qqk~F-rGt0n_46B#8-{kIOn4%-ln#=O`)ajtdL#ccu`S^i zZ>l7BqchIGVVBQ^IJ`eCom6?_dVhy6q%0~V4uP>?K|?48XkF+`ZTXIL0CPmH=|5?d zg^(q}L~iBcSX^cU@H;c5&QTJY7FY7H|>?`NUjdfB(#O|(g5tf;R^0P82Sdf+)g1) z?nn^AuMGB}2Ya5Z2NI<+i2+5ZsXg$Ex2!I(f{&sQq%~iRCoihDu4~JClFinHUEE8eo|rY1LKm!PHP}WK^O%E1(=s4csGjFC;*)rDC&To=jKfi2L|pbx{-1&;>@C@g6V3QD#JH zng)UCY_X8^r`%L(YHUC@qh-v3owAH_KDZGSm$}k z1%TXvhv;gNz%q0wIx`j(tL$Ip94`RWhw&TbYacT|7K~XUb^3f(>1)7fWNK<^K449c zNwpxe(Jl&ec{yg?qaR1!!2n^-qJJS8naoM=X&zYrLL4C|xGs2FpDX}x(4Unm`vdNL zJ#SkxUZnR01}Xpv5;C)E+Gsa(cS|__lnRKsVh#69Ebm<{Xcm1IfvH3?WLV_NBG(w# zm@Q>l>ZUQB;H$!6{ta=-ncVjlTlw*^x@OX%XRm{bB0-mZ*E^}R7$9vY`X8WT4gAUe z3EY`AoJ@7>7PbX&0{cGUWK?8`P^oKVR2{ zd~|TGmz}ZhdkbP0IY2cMTw|#fzsCPyc8i7vy7nTvYn}S}&#C@)M2EhR=XM+*_@P@h z@{=MhQ)<4nX{T42%*{>e_c=Ay@?QSpuNOKX2~$@ERh5>Bs1pW63vRNRR5FKbCaY{40ZC#LBeBb`Q{1;c$nQ2 zg%6iMzcpwDqH@x`=fj=4J-yU5$d;+`QVP_39^0JKpUe{Eyt1tL`^H*TMHTs z?3N7Pnt=|&tLxcOdIaO}b!{Sg3U*1T5oghVQp~9#Vpmsnw+ilx{v$oF8_Sn%bl2)- zU1N0xK=5vh@v}5)*?59=PNlHk`2k?-_}FPpu=bfVZGgIq8F~Hwp$dA_s}M&(`HE^A z*D?{QDvR~(xc>IxqE70zOBo<~L|F0Fb_W&Ra zLk2J%^NE~Ff|{KZBqhiHt(4raSm-7)#nI2N42V%|x}n;t03Po?g>n-xNljiTW#s%g zP~Zp@;KmEP@HzgP^n0Ccd8W0KYi&e^nsGU^MPQ})dK_q;fI?PM=&oS z$UCL;5;b+9#3U6wU!bLbkx1Vm6%FIQ#XBo}j4#&Oj*go@^vr2ZUD8;)S_ja`)DCZg z$3UY?5Q?k|ov@COi$F(@V0*#|NRUni7MPTo{O5dlTcExs251vwvVXjT@cl)y@t)k= z*GNrMIPe^Z(PmV7UK7mx1kC2-9Ds#kO(w6^>n$FV%A{VF2)N`|D=#N9KW8@({5}Bv zydtOH=;r|;u`9yJb>H*NDC2xqYi`RNAVSJ4{c=3)J!oQD6I3SD0QnHi|2jI+=v#QET3<-4}rF z4@udpFtESGn`lX}Q2_JMzY$1wB3_n-i>zx3lGo7 z_|{nj)>%AuqHR)v0jstqBARzr4Hp!%P)C*p?&%&tPB_4KKYF?zaS(z18IrQuv-RJk zY}AB!$fM{)*`8>0l&W8miO)oo`W}$4f+1z!8RPJHOPh5OX_2M|6lb328Ghb-$eM~) zQ3pwA&njSN6}n)Nz@L(%xHJJ55NKqm&P`;7IX(tHiF$p5>EJX?y}Djj?)Jzv+K|^( zjDdX2A-g!XN%UVWjsL=3 z)^Rd$EK3t>Cb#&;a2}pHQK#)axt|d@uH6J#rl$?pd%5w|8jt2b60Mf>zpd84OkHnp z_RLblZqJUIO)j@gJm-TpsH$&$3ZVn%SugaqM`|{y@-emm=QqZcERmOZSn8A9K!-(e z@fR;zY1avmvKyl zb}esym&@YxyPvnC<{$oKo!DYoif6+Mng2<2JsJ85S^@)lKp(#7B*x zTs3on8ce-B3{uhgPtj)C944#3TF_60j9f#4!lKWF<4Y&zfyjyxzsPQ0s!ziAl~{&~ zyFd8_+bC(WuPD<7xHnLNoc2wTOV~(gGY}2OUyQR4WY$q3r+Pu^#8pjAC}KQ! z`WJP~fA&kkGyCB!?#suj*w3{N=%23`*)Ro7sBWpg;Z{-W@FD4|txJWs>XJG1jE>TL zKkb%DI8c9XT(38CC*225lm#ZNjHld=R&cKG_r_S#SyH*@7*Lzd(|6i4|JLY_-RU43hor;bUB-)O*qqh>aN`QS)gby2ep zP#BVltb7I#_1__-J*{tr^K0ObA@f~~Jp9RiDO>Pl- zhJQy``^#`VWUWI5YOa&7q_U3%jJIervgR6P;3Y%;E?w~<;*=(@!1HbulR$Z?d{qAi zEC#cX2jk^Ej1hLI2u#ane%YAG&h=|{Y4l8F#Xoe#T`XmiQW`&MiFAst{8Ojs-(YFV zZsyN%@I48;jS5EJ27VtA>=K{;Wz#kbnrQOW2D zZ0>oy;D-SZ8g&{-7EE4 zN@EdTZ!_xWNi}n&##nFKnQaSD2G3sqfP1g5<=&Ax*+;T)_qv~tRX~Z0Sb!RRr$peT zskb__w!G3138c>7+;G+E#ScW674Zj`HHj&y84?J|NgyS~MRv^8T;PMw(+qtl14ji? zWSb)SZz3<`hVy0u$s9CZE%6ei>6tQbCIk_fRLiamjsaGl$=pZM^lFxNbwMS-HFpf9 zFw11&;rU@%DUh`127`Z<_WYNk6c|zRleFEO$%TO0xZP_^!kFMU1G2=vrdRh-S{q-y zt?|o^3pOE5n!W4ils4$DQ`X-egT>Uy4z*$9oVffJ2H(W5?Venxz2@|HHbavH42{68 zVG2f}tb`tPX6b&z!ad8SU-+n{c~nz1zo|NmpF}k3jR>ws#Q5KsuX+=X2a4sU)iMv} zy}FNgk8iT*(>Vir^ujVoJTF7^zAE*cmHN$i#Ldex@K*osf=1|)S~zy<%-oSUR6Vn? zx-Elg26s_#doLa15PIE&U)QP+d}L@_+}z8GRe1R-QS;{E)xH%FVOcjKfLrU*pv0+O z5@Z%cju?@l_sKm@JPQPqZzJ*$``6!HgVedOES4pjx>hux*sZa!M|%|w8-eO=neM!- z{(E3-3beVyT!o_f=s{$igWq2gBfS<7$1PLY2#3Ea?P%>9~szti(MD;Yq&L z$BYih*vQ(B@DMiLH-m>XG6lcz(63$jL}*vvs1oFBY&xJ$WCg;R2)w}Yl0>cp=V z*6*-q8$BqwyQ^>iTsqcqmyBB=7qK*l=!(7WQ_(*t)6k!@lhgaSzEui%32x!ZkXsd$ zY)5@N9M!@}V`pR{)mWUfK;kC-lN6t#?Qcl_zub4?2Lfe+9L%vCd;M}(ih_w>WB|KX zWQak9{!*%Yb)w%`EHwsruQ%1m&A$|uL!MsLPBTPyA|5^8O9hA)3VUPWwLEw>XCZGX zt6lIPipzBF%ED_7YQPCQKTk>qYShb;$UypxiK%nAFcNcjc^=puC@VD!|rvdh=PH^gK*<6QFCftr^zeLAAf#{5U{1OYxB?B|Trjo#>lE*OabJ#&L zznQEvFSzox@XP5wmt3Xl#kgwAktI)XG!!zYC_`zlx01t0>6k<^t%GFYd6Q|Bv^v(W5%mx+6f-JMO%lybM1*Nn)$;6o-X>ub$cbR`T>XS z^N@y%t{b=2o?mDGcxl#NXoTIbocAJ-ZP6{qABG7pKN(**o}HMvkb?!l@#Aq&RtOjz zW`6T%>3p6n=GXy4Sqw#-_;Y>oU|Xxg5tT2uLoc77ND=V2+MUP9{_qwV0-%~c9>e5x{+a(${x z*b4-&D*IY-;twsY0F-&1ZI)w(9-0>HE?V+zo@q6%8f)bS=kgefabCxq$p&@r_&er} zS}E#Gl-3NCa97{3y-xV%mn2d7G}QiaKo3ph>8kldaC z@uhQ8OG~8pr80r+RE`m!ZFleT2z?GyW#6Gm^B?r;VUv@4K4b(=scUoTb6o%MDSt=5 zF86MVfZngBJFVWe&MsLYYSz|qQZPL1pPQ$_Eby=Hw2Nfq7&rZ0%BBsAX565#?MP`$ zl`Vq1QkBn^W`|-g(5ran*@ihZ@So5F`oBF2fDaQ_L%aBm%2{2B%;~F=w+Rerh1u<@W8U#{4Ge4L{Xe~TQAG%vFzrbx( zuqt^Ydcsk^|AbqA)mG@${R`xkBbCjSKvz|N$RNg}K{c04JY6f5$d$Uku;qn{TUGTM zT6Hle#%*HS@akzi%L2=`m?)OHKvFn}j4eWurU7UF03h*wvM=~7apBYh8J!Fu_3U2# zz$xZ#GwM`ZI#EhZE)ODM)UdqOHp~??-%N011*b`dDCp1<&K&M0Tqe&2%87sd$mGcS zO5lNJ$4Hp?-gtdgL7#z|EN7!nGfXzSee&mNR~NNCxM+V0!6(R&&Ji${(1qu%mlDm! zGnPz=L_Il9%TE(mi;yy1vhXTZk9v)-^IQ34cwU*%k@j6x`W744qR$0MmINxWcVV6s zuW;gTqD!~Z?YbKvmyYVZ^A;$6X9*0$ha8Xls@Ox8CX$?7A-65hC;HqHo4sCh$d__~ zk;+Lhq$uF@s#N{cM(BfLrF~UMPn({U(1t?4NA>dI!C1X^?kRIo7Ag|n{q0>;BS%cs zBlt6Y6_Y2}F@~*vEuJzJASa zEv-kyzuk&`FP$5%8d|8P?mTiMUIP75-+VghD=CY2(r&oAUacA<#v{5I`3a@q7s8C* z(VhMc97kpkT}K9PEMB=Fc3yDg`b_ogliZ!dq5S%z#u33qy_2jn$NMIE2p%X!7UD2^ z?eBLVgeo|l=f7XUDcrwY1^bX@HzMt1}tF_gZO=34iB~-2)nJy`E zbP?m&tuP3=LT1KR+o8fr5fgHUu({9Cg`zR;n~8BV#uyC7@O!;S+P2#E+kSulwOfz+ zcptC#>-Bs+U(e^`M<5Na&1-a!af8J4n91H9b~_rKeZ#U2TQuL0NHS2RXz%K0M%&;$ zr|6Rcv#q=brGxsM?jMZu+hU&?uOUYInEt?aYo0j`DlO5jL1}%&_2>IrWoopT5AP16 zRJ*f_WG|g>HosVuY?bw>72KC3CBpEIE}}uLGDBL;8XJgRzTEa6va$n4yoI!>wS(pB ziFYr>wpNa>-7u)Qf>T+soU?(!JDHDf2qXmQ-$~{*CMOPdN33*^32a@>$KZ^P*VNbj ze2vS&d3oF;^6ESZqjFU6z_W6@xtKv?Q5l?mfIG#V-h_&lhZcFc|s0X>sLkW~=Dvo#LH? z4mJ6|1^++~Rm~Sy=S3zI=U*|HA?|+^QTJLhzXws$DL^D)|f6@uuXI%cxz3@=*;sB-Sd_HlN{mekFo?R1g0Jfj41ZYU)4Ij zPYZ7_XtE~>Sq|65#~1Nj+SQatsoqrK&>QU@DH&ePg&xI^1ZM>Lh(++Foteb`%o3Dpaf)NyzoTtx7i3l3hmYSQTI>@r zZcdz9)|9n@*wCud6p0b0fS>9U(E*GoD8O*diFvOBiM@d(mjzAhJ#Fz4?gOVpu{(Xu zj4@C}4)_+zjP);#pWelMvQ)8Ik9SgSY(wy_3S+OXivbD+TW8YExakqbh5aW*JuJI> zr1o1g2Od_ch{YACk(<=_{$dOdYOU7jRnKSMU*|tT^B&dC%G`m}1Y7x4E=TARLg!fo z>ENYC?Of9>qg{vaM7g$;Eob2gbOz^}UVBl)1jSJ#kruJ$r($mWlV!fAfKEChz3>Ea z%+hmA>(bsCMhN35;4FF5M!dtPJPXS&Aq<9xvA7xjvv*f)K$VV4;>e(HRIGW{M4f2Q z&TCz@T44J;9d9U49Qn^P%01i&Z`^k#>&imw4vFm#30__C#8A?0`VYP{8bzX4inz|{ z<*49uE`z8G6LCoYZusKI#MaJ|M~PVt<=gv@#x*w6W2M~gwYRJwPYTAqvZ?50jvnon z*H6wlW_*TrjuqY7xJkZWI6X4UMpDT41a=+ItrKOg z-<}cS$S3-8h`(UYT4h}D_Ll(cc4q64TDWc1@<753t$}<1B~Q!%?p>F55E90l-WNDG zwUTQB+e#ngw=K1QAmFQ-WTuwXn?iKx&CglY_RJ#im!j4NjstEGC$Qkj9OJQdruitjkK7_Pbd3}c|RK33yn_aXv&0~Xc-UM zcsTvZL#Jw=_M}9d>bl53ud_u#d*D3l$$e`9RWGn6+Ay#xiKq}ExqB=_)4?K)6+8V-ec3}%l8 zKCA=lxwRXx?P{^3guLm={)Gxm6ZfBgHf|yoyW)!{6HG_rM=|4BzJkg!a$5xAo)@N~|TC1;JsTJPp}zYx5*%dEV*0$ObTr^R_XS~^4nnYpk$GA4D{!zhc8bFMwFa=B)uE`xt8K89JThe?yU1jDx z;fbnx1aAF3LoA(mw5D}aJC8N#{o~bwKdd6hC3o}AHsvlL>+3$Wn>uv+LF2FQ+ZFK1 z+=uBB)9o44f{}EyolR)!)(rGy%KRW8|sC}O1?Zc5a%$VkbK&AFDw|-$tty_uO(9`5YXh|^R^c z2j$$(2R34vCKevQKJxmhcB$gIE2Pc&TtV|A$HJmHBDHd+J76~~r~5_?z157@6oyZTZcBWL|lrXIzl-XDq!i=U{)XtALm{ek* z&av6U@f^A-Bg5K&bDIdEO@vGIn9-ZeN#-2lu&=d*hHBJ*@>yvJ!R3=VAGP$LT*sGSXvN#q=bcQ|YOa(b=4eg*WQa{JkIX+*DIuiHs7p7ivYSHYpEv>UouRek zUV{6?9&(8cjvZ!NW2Q%RrEe-62hZtlPqlGR%PEhC`Ly8TDj`hOG;gK0cs^AX{HKJ| z0Y!f$uZ2_fN^Ke6WKtN}l&ya0Aop4$*X z-7@YaP{0tVUBbamihTUws4`SqAp3Hf1|b z6*&)ITd>NR9-H7ip#*9MtON3Yu}nkre=8v?DSCHu$HLT(#$^i$-#axZ5hxyghPw|zBo$dJ% z+m`sv`ca?1mb^=yCnz_l^GPlK;bk6*4-c8B7P2`#9x>L`8en6r_ zGjQ^rh?=z-Y!<@bF6%u6?#P-!$+3oMyGT2K$t0bofg>b3Wze&-Uz{=zhQ&EhtogXg zhUtzp&c;A1;BkDcaa7h*qf^t6RS%Z%_CvtLdsT#;yO;Zp2KMLyXQ$0ams~^!jb$9+a%JGHNPGk z_whFj+_8UcruEd9N&(}0wTWLKUN19E}BTG*>gVEyN<5zIGT`%tv~3|(UnE$6k~R^AK{E&tfWXouXvLNQ0@QXL-mHn>iEXElB)02 z!rS1+4ZMp5?vk@|p!-w$tL}{MmSR>8Zk?2k7rt1Ap8ov!H0uUU!BQ?>lQt7xmuAC> zzgT89Wwbq^j~!plnjGgG%SiJK63u}&ICE`7Ueht96%f(w7EPPbMoq** zpG%cBmZlX^S@hzo4LmZFOZFoaG8$8m)#$7H%Oae9QoTM^Gz|5OrI-Ox-ABvd6>f&b zv|&hCLq@dN>)3Avsoa|L6eclW2N?Km= zz$&$nK3@0-akZ+~HsXYEfv|mnLakC>#65= zbZy6wM>8XHwY#u(@ED`JeXNeLAxYed*$+cTRssSdnP#HJKTv)Et;$V}3 zE9&{?e%4assaq2;s()(2hau|T;rHm-IFB~Ndt^}tHT~Aw6O++qlhJ+&n=k%Ete}~o z{V4Ft(T*vPZ8~#JWzD`7_Zcl5JeA}8Xn#?`Kq+}(1mRyxN6Hh~Il+Z$Q3>Z(W!4Ou z#zk-#(=!=O#~S)pVkC6#{h)LOjHbQ~mP3tr*%&Xk*brCPngHBmXOggh>d@o69M@L& z*j9@ZvGT-eUcn3}))VnYvIvJy+D1L|zee zPG8Gt(^cBYK-3`&t>}+fmNtO)>u0oI_cBxWKYqwB1@~7<*mVZD)26?&<2b;h+?9T) z#8plu$Dqr(A*H)wmz8IMX5b9N-jn-6=JqKwR`B>`H)E6U3w|CP#3cRhh1GQlgsAk0 zHt5Qkzjpu=ESG$~CPAlQ=(3Ek&9`5GvtNuG}=U`N?X=zqdK;uGn&(%p+0v6&$`W?(&aTj<~; z+ks>rZ`Vn?I>2~>Wf`_3<4D?Gx0qw6UZY%-m2T=96hI#wBdCT2M5?u(3LuobJy)}u zt{soyGn1zNhM8n}oG$SyW(zzHO1s~G97>4lmn4MLCJ)m!sHMq9%|=}P*mRc?mp+eH zAG7xUz%wn%TI^zSC%Ix|nJwN-XUaK0*7=^apBoI z6Ibo2LN^ZKWSGCuYKB=y0VMS=TF0C@=gg2;KygM`VHmK&wWsFgWGTmc2(wg8BcnY! z^{hM+Z;0>BUHyG=V#4l|5Ti@h=Z~~9B=@uja-%l{3!a}jN8t6FnKk13Tn(I8Yb_;@ zai7z(PFhsfY=E`)W4w-fiDZs$6dHBCkhX zM#wIf5qVJ0sBuEt+ZAf9H5s^dF7nqoUKYpXOf)H9GjdzTCs0#9QKa_ZgwGYjfn45B zEoFt8tj#fr%(JnV7Zw0@M|EtcTB9z$Kv%AXRzh@%|fDh$U>IdqeG>vQ`k`s%}S|{8PYelkG^a)3U7n201r`b4Ir%8yG- zS8!W#U&@Q}dNfEtdFqO|A#L4G(_B+(*A}nzrPw2!80v6PBHvSg_^JenSch zS$!?`a<0MNlBY?S34e^0f{+rWNHkmCY((8mZg|qWtLXK;)~t1L4OzCv?Ax)b(eA+W zQ>rJPezsv}LsomtM18TELivy5GI>K!FK|rm9h|5=hv8LWTFx{t(AHh3blsDy9?0Ui@FfK zlzp#T)v~I)aDP=|!?@`K@$JhD>$6(0?8|23ms8hypPBI};CN7qq<&bKqfvxN#7l;E zq*VMSA+HoVR2gKTTUzl-rMZ1EPF49{Fy5v~{gc>P^SGbbP6I_^A7}@@=U7cA)+i9c z*{20LJTia&kIev<@5*i!%04$%I&C%k7Qq%)Wf56|o{zl34r=da#2!OmFP-PB|ok>V|cP63a9Z!{6i^}XA)=@B@M@Y&$=JT7lHTiw9pcUuQ zkqibEW_iD+k0t7y2COsffxC(wGu@Th>a~^W-jqmDH0I7MEoL<7U2mTktafqWlBCV| zeFRPUr0IrKOX`6YxWg0DtlPDt;ks4@SQ9jmbAV=LY&Z1>xj(a3(KhpevXsV+_Hr&f z&7Bh{bFJZ9a0b{!-}tMx?2)W@PU5|&x4Z*n~}vxc>;} z#WyXqsI$m-4W>j>KeltD2Sc?8E=!R*K$;#F{0Q2J*dS>iL{PqH8uj?h7v3#u!!N{k zG70S5$dK>4;@G!h{3Rx3s}zlVaH?(4aU0BImp$RN*=My~QI70}=n1$&2hy~FS@*iP zN3}cJ->x$wNL){@FFB_#-cRzvaO7QDPu@tw=52tfiV+FTmZ zh-P3iGPTp&BUr7<6qD>A6zJY}?;P1F1gErI>f<=oIA>b&81p@Z$F$4q`xBPp$dc|MKc%B+BG zo?17KME8pAhY#vFWE#RW2BYhJNUz}|Ea!K&`u(5-B2F&k=zVkEtCoh@u)`DK_LG4W z4B;6`NRfEEqXNupdsb0gV&pHZO7z7C=_3@fSA%X;J0-O<2QI-l&KOxZyO5m-|FkS0 zz0_|6LptA>y(zknuR;MM+AZcHHg2yw;Wf0?|(Sq zbk@a^UF%v9oBg^Wu%t5j7=M5Ev_&Xf*f{w@W>#c##V^wV3Wph3toKV_K1hF$kDd0t z83w6T|EnMGCb+XN{6Z6;IJtO4XMRPc+k-dr2=3e8hpWOnf?KD;k4`1b85a86J=&fVTYld;MXR{ zoY5ISf~HOZY1GeoPhtFW>7TiCiPw)tLIQVYeYHVpc@qq+hti9E1s2wfH-L3&YD!8a zSbuoz$hZlzWI8So#rKgiFDVdz^6Yrwx6TdUP1ROhYj@7n#l-<{Dj5=~3__nZT^@(E ze+1{_*}2kVBzqP$w=q*0>5{rdMg04t(vUoEdTp!{COIczlr`EElKIBLL&P&7;x;Rg zdUjf!nJ2-iKQXhf_khWMSS+DOKew*{?V*<(Rnjgw!s+!WhSgZfPSien6$xK-{D1r+ zYL=OUN9NI39q%R1$PC$YX4=no)x>jhO`I*1)iBqIdzOit(hJ6v`61Kn*u<_}rucW- zqS>>??~T@E7h}S4*tqp5hW`&6x0(YUg$~*=vlFHuqG;PXIC&0g#GmZA``O+_Rin1h z4KPZtZnPwGabNCa2T{*}opp`gh@VoLDw3@l4YFTL*N-P89Q8$M{$?aV_zC(rJaNLk zvl&3=zVD>GuaD#eRYswZOkOUMXX5*T5uq*WP?d!&zWeaqlkh_tp&#;Ze7yfI zNt%@&>s27?8yLV{|+G;yxjB13A*kP9u9DZsluMA+95D@7E{-gS|;VGDuNGH(dxC92mxzLy!% z8~H36ZOhF%0sQNE6g08?3W?w`-;to`BG>;EQbCYi zv9wenT?)KdefLE>NJ-KvBe5WoV5K5r;L3WW@c(ieen+v{b9t^SOWAy8ee6a%Xw}W*(Q@x>E=8j zC#^{qOSPVVFu@QMV5*k{kET~;fF~H;kBELNZc;BBrxd|@p~y#4|2`kZCny4bF`C#4 zrIE=SS#`7bWYy==6p(%}qOBq{DZ*16YD7zGiP$VfYs1Q2$grpROq%|P4rhs^_l>*E za%;Hcx0W16)4S5E%3PCH{JpUIpHFh-`*2erf ze$_|H2y>0@RAEb{2xG8TUz$K<(Z&n3Jk-8_)23DA&X_KJnV5I~p^{8F*K~Mn!?NP+ibHd#jvlnxKN~lBDwg_$8xY6*l`NlQDIagv#N3Lz?qfRQ;p{C3cH4 z4U^pA$W}O1W|altwP^0g(Uv$hPL#Ps{F@;AX4>yIa&edy&uzVKFHZ>*%o}d(x@c(@ zpBa~gvf1S@a9ZjrI{7McQT4*W?d2NLte(3#W6M+IXqT`%pzqq(3|aL*78@VUst=9X z5D0{=ZU{aa%w^h11Afw_E_42HYDR{_g!*EkNA@mz=I(Ujcm}FMGmDk8a#G#Mw}20Hr{?G^*kIHf@m?QGT9MdsfXa_So8D_uHW$B;(Yy-6c7`>-@hSmJO`)+9Jfu0=u_O!vM>@$v|=;DJzTWZBW!#39(u zXndG9xxx|Zg1UcS7nm2cZw`a3X6eEvkQd3$$;qjfgmJ9$;E@Y1nw?fCt>F$OQoD3T zRh2W;Hp7y^*iEO0-{dQLz}aElud_bLv07qu&s5lg zeg}`s(J(AIN$Wd}X2np(N0_KJV8_actflFrt=o&f!*Ft>Vtx(?!~`Q9+QW3q(9#s= z;B$vSN7y6yl&^Oc#QqTbe;pki3Yy1P*PU(@GV=ZJJ)S5*7{5ErJo<~5~b%8nSRE{enIYiEbw4w>=xZ!bSsA*@b z7h77?E>noUP;(=F3pv^+YFavREryt9Xl5q5dT1p^%<<+55H||XrMi-v={8I za2&DG*L`IcM(nGQF=$+z)s~24esz7OAY_Nb9)&Vv`ZxF0k{3kuuHTI_F3W^$m7+N3 zaXwe7euRwki9l`HoQ#{?$Bxa18DafXQ`@98*71V_drXzkq{;sf%TTfvjT8qC&4k?k zq}&DDb**pJp8umJ;X;oxA|vWw&$jEv*S*v#^>^>XJN?_(aGTd>I$C8r1vVfGHa0e$ zf-*ltQ(#5IY*kfJR+9W2rdoY&L zS6SSDkEy)U3hLJX;RL0awImQ5y~DuR(E?343rgeA_q?g{D$1%dLA1N;W#p;QX!xF4 zZ51j!!R{+c*TF~my9ixNyFaso=CY>>rYeFRyuI%YlW4a4cLJDBPcq3#3mVgH3{pYgQ=BZek@)pu3Z^?(dZirg)zNO! z|6jtBzl3HTjL~i82`t3jmi!KPY%7(8x;Z)(^9CU|X6L zP4b;OUMveg6EC8McN@yVeMw1OwvSDnNV>5YqFePu7rq-Lcm75F_C}!XEnP6pSf(j6 zYuzsZ6KGXjPuF8}RpGZAK=r|lV8~eostc;%^tV99EsqHh) z%j*fBGV}g1Sf?y=`8|}PfA}LdDQ@~5@ofNig#al)nFXvrT3b<17x;)`TKCZ<0uZ3p z2a-6!0NGgB+S(4`4Pn~brDQG_Gw1HNpWcEMov2QnU8WZpA%nnJDjX#Jvn<}ON3YJS z>ji2}N+l@MTuT1OCwXlDRt<=MO{iy$D7^CdczYcvEb-!LO_rkDPYx4uPNo>

>o|z4F#SvXV0t#Q?HP|H}87DU{eZkfe8=D6~nf) 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 diff --git a/docs/white-paper/main.tex b/docs/white-paper/main.tex deleted file mode 100644 index 20a7616..0000000 --- a/docs/white-paper/main.tex +++ /dev/null @@ -1,381 +0,0 @@ -\documentclass{article} - -% Encoding and Geometry -\usepackage[utf8]{inputenc} -\usepackage[a4paper, margin=1in]{geometry} % Standard 1-inch margins for better layout -\usepackage{parskip} - -% Math Packages -\usepackage{amsmath, amsfonts, mathtools} - -% Graphics and Figures -\usepackage{graphicx} -\usepackage{caption} -\usepackage{subcaption} -\usepackage{multirow} -\usepackage{tikz} -\usetikzlibrary{positioning} % Ensures compatibility with Overleaf - -% Hyperlinks -\usepackage[colorlinks=true, linkcolor=blue, urlcolor=blue]{hyperref} % Load last to avoid conflicts - -% Floating Objects Placement -\usepackage[section]{placeins} - -% Bibliography -\usepackage[ - backend=biber, - style=alphabetic, - sorting=ynt -]{biblatex} -\addbibresource{references.bib} - -% Title Information -\title{EulerSwap White Paper} -\author{Euler Labs} -\date{February 2025} - -\begin{document} - -\maketitle - -\begin{abstract} -EulerSwap is an Automated Market Maker (AMM) that improves capital efficiency using Euler lending vaults. Unlike traditional AMMs that fragment liquidity across multiple pools, EulerSwap allows a single, cross-collateralised vault to support multiple asset pairs at once. Through the Ethereum Vault Connector (EVC), market makers can borrow the out token of a swap using the in token as collateral, unlocking deep liquidity. This model enables up to 40x the liquidity depth of traditional AMMs by making idle assets more efficient. At its core, EulerSwap uses a flexible AMM curve to optimise swap pricing, ensuring deep liquidity while maintaining market balance. By combining on-demand just-in-time liquidity, shared liquidity across pools, and customisable AMM mechanics, EulerSwap reduces inefficiencies in liquidity provision, offering deeper markets, lower costs, and greater control for liquidity providers. -\end{abstract} - -\section{Introduction} - -EulerSwap is a novel Automated Market Maker (AMM) that increases capital efficiency and liquidity depth beyond traditional AMMs. By leveraging Euler lending vaults and just-in-time liquidity provisioning, EulerSwap enables market makers to service significantly larger swaps while reducing the need for fragmented liquidity pools. - -This is achieved through a combination of advanced liquidity mechanisms and customisable AMM curves. Unlike conventional AMMs that require separate liquidity pools for each asset pair, EulerSwap utilises a single, cross-collateralised vault to support multiple asset pairs simultaneously. When a user initiates a swap, EulerSwap borrows the required out token against the in token as collateral using the Ethereum Vault Connector (EVC), dynamically scaling liquidity without requiring large static deposits. - -This liquidity-sharing model increases capital efficiency, allowing EulerSwap to achieve up to 40x the liquidity depth of traditional AMMs. The integration of \href{https://docs.euler.finance/developers/evc/keyConcepts?_highlight=operator#batch-operations}{check deferrals} and \href{https://docs.euler.finance/developers/evc/keyConcepts?_highlight=operator#operators}{operator features} further enables market makers to automate liquidity provisioning and optimise capital usage. - -Beyond individual swap accounts, EulerSwap enhances liquidity further by allowing multiple swap accounts to operate within the same lending vault. This modular design ensures that idle liquidity is repurposed efficiently across multiple trading pairs. Much like Curve’s 3pool, but generalised to any number of asset pairings, a USDC vault could provide deep liquidity for 10+ correlated assets without requiring separate liquidity pools for each. - -EulerSwap’s exchange rates are governed by a highly customisable AMM curve (illustrated in Figure \ref{fig:fig1}), which dynamically adjusts incentives to maintain market balance. Unlike traditional AMMs that use constant-sum or constant-product formulas, EulerSwap’s curve allows for asymmetric liquidity deposits and single-sided concentration. This flexibility enables it to simulate the behaviour of atypical AMM protocols, such as the MakerDAO \href{https://mips.makerdao.com/mips/details/MIP29}{Peg Stability Module} (PSM). - -For end-users, EulerSwap functions like a typical Uniswap-style interface. However, behind the scenes, it incorporates advanced mechanisms such as dynamic borrowing and repaying, customisable pricing curves, and shared liquidity provisioning. The primary target audience for liquidity providers includes professional market makers, token issuers, and DAOs, while swappers include leverage traders on Euler, aggregators, intent solvers, and MEV bots. - -\section{Swap accounts} - -EulerSwap differs from traditional AMMs in that it does not use shared liquidity pools. Instead, each EulerSwap instance -- known as a `swap account' -- manages liquidity on behalf of a single user or entity. This design provides customisable risk parameters and full control over leveraged positions, making it ideal for professional market makers, DAOs, and algorithmic traders. While future iterations may explore shared liquidity models, the current system prioritises capital efficiency and risk isolation per account. - -\section{Example} - -Suppose that Euler allows borrowing of USDT with USDC as collateral at a loan-to-value (LTV) ratio of 0.95, and vice versa. This means that for every \$1 of USDC or USDT collateral, a user can borrow up to \$0.95 of the other asset. - -Now suppose you have a swap account with 1M USDC deposited as initial liquidity. Using maximum leverage your account could support deposits of 20M USDC and debts of 19M USDT. Alternatively, if you swapped your 1 million USDC to 1 million USDT, it could support the opposite. Let’s say another user wants to swap 10M USDC for USDT. The steps are as follows: - -\begin{enumerate} - \item They send 10M USDC to your swap account as the swap input. - \item Your swap account deposits the 10M USDC as collateral in Euler. - \item Your swap account borrows approximately 10M USDT against the account's collateral, which includes your original deposit, alongside the swap input. - \item It sends the borrowed USDT to the user as the swap output. -\end{enumerate} - -\quad -Importantly, this isn’t a 1:1 swap because: a) you charge a fee for facilitating the swap; and b) the exact swap output is determined by an AMM curve, which factors in increasingly large price impact as the swap input amount increases. After the swap, your swap account now holds 11M USDC deposits and 10M USDT debt. It earns interest on the supplied USDC but must also pay interest on the borrowed USDT. - -Later, when a swap occurs in the reverse direction, the incoming `in token' repays the outstanding loan, and any excess collateral is returned as the `out token.' The AMM curve dynamically adjusts incentives such that imbalances encourage swaps in the opposite direction, facilitating natural rebalancing. This mechanism ensures that positions do not remain open for extended periods, reducing exposure to borrowing costs. Over time, you will incur costs due to small interest rate differentials, whilst generating significant swap fees through utilisation of idle liquidity in the lending protocol. The whole process is depicted in Fig. \ref{fig:EulerSwap_liquidity}. - -\bigskip -\begin{figure}[h] - \centering - \begin{tikzpicture}[ - node distance=1cm, - every node/.style={draw, text width=2.5cm, align=center, rounded corners} - ] - % Nodes - \node (user1) {User Sends 10M USDC}; - \node (EulerSwap) [right=of user1] {EulerSwap Swap Account}; - \node (deposit) [below=of EulerSwap] {Deposits 10M USDC as Collateral}; - \node (borrow) [below=of deposit] {Borrows ~10M USDT}; - \node (user2) [left=of borrow] {User Receives 10M USDT}; - - % Arrows - \draw[->] (user1) -- (EulerSwap); - \draw[->] (EulerSwap) -- (deposit); - \draw[->] (deposit) -- (borrow); - \draw[->] (borrow) -- (user2); - \end{tikzpicture} - \caption{\textbf{Swap flow in EulerSwap AMM}. EulerSwap’s just-in-time liquidity borrowing. The swap account dynamically increases liquidity by borrowing the ``out token" against the ``in token."} - \label{fig:EulerSwap_liquidity} -\end{figure} - -\section{Virtual reserves and debt limits} - -EulerSwap AMMs utilise virtual reserves to simulate larger liquidity pools, effectively increasing the depth of trades that can be serviced. Virtual reserves allow swaps beyond the actual reserves --- the initial collateral deposited by the swap account holder --- by permitting borrowed liquidity, where EulerSwap dynamically loans the out token using the in token as collateral. - -Each swap account can configure independent virtual reserve levels. These reserves define the maximum debt exposure an AMM will take on. For instance, if a user deposits \$1,000 in collateral and sets virtual reserves at \$5,000 per vault, the AMM effectively supports up to \$10,000 in combined swap depth, with a loan-to-value (LTV) ratio of 83.3\%. - -Note that the effective LTV must always remain below the borrowing LTV of the lending vault to prevent liquidation. Additionally, different AMM curves influence whether the maximum virtual reserves are achievable. - -\subsection{Reserve desynchronisation} - -Unlike traditional AMMs, EulerSwap does not hold user funds directly. Instead, it operates as an EVC operator, meaning that all liquidity remains in the wallet of the account holder. This design provides enhanced security and flexibility but introduces the possibility of reserve desynchronisation. Causes of reserve desynchronisation: - -\begin{itemize} - \item \textbf{Interest Accrual:} Over time, collateral deposits earn interest while borrowed tokens accumulate interest costs. - \item \textbf{External Fund Movements:} A user may manually withdraw funds from a vault, causing EulerSwap’s internal calculations to diverge from actual reserves. - \item \textbf{Liquidation Events:} If an AMM’s loan-to-value (LTV) ratio exceeds the vault’s risk threshold, automatic liquidation may adjust balances unexpectedly. -\end{itemize} - -Users must periodically invoke \texttt{syncVirtualReserves()} to update EulerSwap’s internal state. This function recalculates actual balances and debts relative to the vault and adjusts the virtual reserves accordingly. - -\section{Curve} - -The space of possible reserves in a EulerSwap AMM is determined by how much debt a swap account is allowed to hold. The EulerSwap curve passes through an equilibrium point $(x_0, y_0)$, at which the marginal price is defined by: - -\begin{equation} -\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}. -\end{equation} - -Unlike most AMM curves, which are usually defined by a single convex function, EulerSwap uses a piecewise-defined curve, with different functions providing trading behaviour either side of the equilibrium point: - -\begin{equation} - \label{eq:fx-main} - f(x) = - \begin{dcases} - f_1(x), - & 0 < x \leq x_0 \\ - f_2(x), - & x_0 < x - \end{dcases}. -\end{equation} - -In the domain $0 < x \leq x_0$, the curve is defined by - -\begin{equation} - \label{eq:fx1-main} - f_1(x) - = - y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-x\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{x}\right)\right). -\end{equation} - -In the domain $x_0 < x$, the curve is defined by - -\begin{equation} - \label{eq:fx2-main} - f_2(x) - = - \frac{ - \sqrt{ - \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right)^2 - + 4c_y (1 - c_y) y_0^2 - } - - \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right) - }{2c_y}. -\end{equation} - - The $c_x, c_y$ parameters here are liquidity concentration parameters that control how liquidity is distributed along the curve, with values closer to 1 concentrating liquidity around equilibrium and values closer to 0 distributing it across a wider price range. A full derivation is given in the Appendix \ref{sec:appendix}. - - \begin{figure}[h] % 'h' places it here, 't' for top, 'b' for bottom, 'p' for separate page - \centering % Centers the image - \includegraphics[width=0.5\textwidth]{curve.png} % Adjust width as needed - \caption{\textbf{EulerSwap AMM curve.} The EulerSwap curve (red line) consists of two sides with separate reserve values $x_0, y_0$ and liquidity concentration parameters $c_x, c_y$, allowing liquidity to be distributed asymmetrically. This means liquidity can be more or less dense or concentrated on one side of the AMM relative to the other. The exchange rate at equilibrium is determined by the pricing parameters $p_x, p_y$ and is fully flexible. You can interact with the curve \href{https://www.desmos.com/calculator/gzwmvbs1dk}{here} on Desmos to compare its behaviour with traditional constant-sum and constant-product curves (black lines).} - \label{fig:fig1} % Useful for referencing the figure in text -\end{figure} - -\section{Conclusion} - -EulerSwap enhances Automated Market Making by leveraging just-in-time borrowing to expand liquidity depth dynamically. By integrating Euler’s lending vaults, it enables market makers to amplify positions efficiently while offering a customisable AMM curve that supports concentrated, distributed, and asymmetric liquidity structures. These features make EulerSwap adaptable to a wide range of trading strategies. However, this efficiency is not without some trade-offs. Swap accounts incur interest costs on borrowed assets, which can erode profitability if not offset by swap fees, interest on collateral, or token incentives. Additionally, EulerSwap inherits Euler’s risk parameters, making it most effective for correlated asset pairs with high loan-to-value (LTV) ratios, while volatile assets pose higher liquidation risks if positions become imbalanced. Despite these trade-offs, EulerSwap represents a breakthrough in AMM design by repurposing idle liquidity in lending protocols, reducing capital inefficiencies, and optimising swap execution. By catering to professional market makers, DAOs, and algorithmic traders, it positions itself as a powerful tool for on-chain liquidity optimisation. Future research could explore optimal strategies for setting liquidity concentration parameters dynamically based on market conditions. EulerSwap's design opens new possibilities for AMM efficiency, setting a foundation for further DeFi innovation. - -\section*{Acknowledgments} - -During a security review of EulerSwap, Chris Michel noted similarities between some of its underlying concepts and BlackHoleSwap, a project prototype he had reviewed years earlier. While EulerSwap was designed independently and without influence from that project, the resemblance is significant enough to warrant its recognition here as prior art. - -\newpage -\section{Appendix} -\label{sec:appendix} - -\subsection{Curve derivation} -\label{sec:curve-derivation} - -We begin with an Automated Market Maker (AMM) holding initial liquidity reserves of two assets, $X$ and $Y$, denoted as $x_0$ and $y_0$, respectively. In the absence of trading, the AMM remains at equilibrium at the point $(x_0, y_0)$. - -Our goal is to derive a curve for a trading function that supports swaps between the two assets with the following properties: - -\begin{itemize} - \item Passes through the equilibrium point $(x_0, y_0)$. - \item Maintains an exchange rate, given by the slope of the AMM curve, of $-p_x / p_y$ at $(x_0, y_0)$. - \item Allows liquidity concentration to be adjusted via parameters $c_x$ and $c_y$, which control the liquidity available for swaps to the left and right of the equilibrium point. -\end{itemize} - -To develop such a function, we first introduce two fundamental AMM curve models. - -\subsubsection{Constant-sum and constant-product AMM curves} - -The constant-sum and constant-product AMM curves are given by: - -\begin{align} - x + y &= x_0 + y_0, \\ - xy &= x_0 y_0. -\end{align} - -The constant-sum curve is simply a line, whilst the constant-product curve is a hyperbola. They can be thought of as two extremes when it comes to the distribution of liquidity. The constant-sum curve concentrates liquidity at a single exchange rate, whilst the constant-product curve distributes liquidity across a wide range of different exchange rates. By default, these curves intersect at the point $(x_0, y_0)$, where their slope is: - -\[ -\frac{dy}{dx} \Big|_{(x_0, y_0)} = -1. -\] - -Since real-world markets often operate at variable exchange rates at equilibrium, we introduce custom pricing parameters $p_x$ and $p_y$ to allow flexibility in defining the slope: - -\begin{align} - p_x x + p_y y &= p_x x_0 + p_y y_0, \\ - \label{eq:exponential-form} - x^{p_y y_0} y^{p_x x_0} &= x_0^{p_y y_0} y_0^{p_x x_0}. -\end{align} - -The constant-sum curve is now a line with a slope parameterised by the ratio of the pricing parameters, whilst the constant-product curve is now a weighted hyperbola. Taking the derivatives of these equations with respect to $x$, we obtain: - -\begin{align} - \frac{dy}{dx} &= -\frac{p_x}{p_y}, \\ - \frac{dy}{dx} &= -\frac{p_x}{p_y} \frac{x_0 y}{y_0 x}. -\end{align} - -These results confirm that at equilibrium $(x_0, y_0)$, the slope of both functions is: - -\[ -\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}. -\] - -Whilst these curves sufficiently generalise the constant-sum and constant-product curves to an arbitrary price at equilibrium, in practice equation \eqref{eq:exponential-form} has limited practical application as a trading function because it involves an exponential form that is computationally intensive and impractical for on-chain calculations. To resolve this, we introduce the concept of artificial reserves, which simplify price calculations while preserving trading behaviour. - - -\subsubsection{Introducing artificial reserves for simplicity} - -Note that in the interval $0 < x < x_0$ swaps should only increase liquidity beyond $y_0$ and deplete $x_0$ liquidity. That is, our trading function in this interval need not depend on the initial amount of $y_0$ liquidity. This suggests that we can split the domain of the AMM curves into two, and replace the real reserve $y_0$ in the interval $0 < x < x_0$ with an idealised artificial reserve $y_v$. The artificial reserve is chosen such that the value of the reserves, as weighted by their price parameters, are equal at the equilibrium point $(x_0, y_0)$. That is, we have - -\[ -p_x x_0 = p_y y_v, -\] - -such that: - -\[ -y_v = x_0 \frac{p_x}{p_y}. -\] - -Substituting this into our pricing equations for $y_0$ and simplifying, we obtain two modified AMM equations: - -\begin{align} - y &= \frac{p_x}{p_y} (2x_0 - x), \\ - y &= \frac{p_x}{p_y} \frac{x_0^2}{x}. -\end{align} - -Since these curves no longer pass through \( (x_0, y_0) \), we correct them by adding back the difference \( y_0 - p_x / p_y x_0 \). This leads to: - -\begin{align} - y &= y_0 + \frac{p_x}{p_y} (x_0 - x), \\ - y &= y_0 + \frac{p_x}{p_y} (x_0 - x) \left( \frac{x_0}{x} \right). -\end{align} - -Note that simply shifting the curve up or down like this does not impact the slope or shapes of the curves and therefore has no impact on trading behaviour. - -\subsubsection{Unifying into a single curve in the region $0 < x < x_0$} - -To create a single unified curve, we introduce a liquidity concentration parameter \( c_x \in [0, 1] \), which determines the curve’s behaviour: - -\begin{itemize} - \item When \( c_x = 1 \), the AMM functions as a constant-sum model. - \item When \( c_x = 0 \), the AMM behaves as a standard constant-product AMM. - \item Intermediate values of \( c_x \) create a hybrid liquidity curve. -\end{itemize} - -This gives the final equation: - -\begin{equation} - \label{eq:EulerSwap-1} - y = y_0 + \frac{p_x}{p_y} (x_0 - x) \left( c_x + (1 - c_x) \left(\frac{x_0}{x}\right) \right). -\end{equation} - -This is equivalent to the function \( f_1(x) \) given by equation \eqref{eq:fx1-main} in the main text. - -\subsubsection{Extending the curve to the \( x > x_0 \) region} - -It is important to remember that equation \eqref{eq:EulerSwap-1} only works as a trading function in the interval $0 < x < x_0$. For \( x > x_0 \), we construct a reflected curve that also passes through \( (x_0, y_0) \) and maintains the required derivative: - -\begin{equation} - \label{eq:EulerSwap-3-inverse} - x = x_0 + \frac{p_y}{p_x} (y_0 - y) \left( c_y + (1 - c_y) \left(\frac{y_0}{y}\right) \right). -\end{equation} - -Since this equation defines \( x \) in terms of \( y \), we invert it by solving for \( y \), leading to the quadratic equation: - -\begin{equation} - y = c_y y^2 + \left( \frac{p_x}{p_y} (x - x_0) - y_0(2c_y - 1) \right)y - (1 - c_y) y_0^2. -\end{equation} - -Taking only the positive real root, we obtain: - -\begin{equation} - \label{eq:EulerSwap-2} - y = \frac{ - \sqrt{ - \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right)^2 - + 4c_y (1 - c_y) y_0^2 - } - - \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right) - }{2c_y}. -\end{equation} - -This corresponds to the function \( f_2(x) \) given by equation \eqref{eq:fx2-main} in the main text. - -\subsection{Invariant derivation} -\label{sec:invariant-derivation} - -In traditional AMM protocols, the curve is typically defined as an implicit function of $y$. For example, the classic Uniswap AMM follows a constant-product equation: - -\begin{equation} - xy = x_0 y_0 -\end{equation} - -where $x_0$ and $y_0$ are the initial liquidity reserves. This equation defines an invariant condition, ensuring that any valid swap must satisfy: - -\begin{equation} - xy \geq x_0 y_0. -\end{equation} - -This condition guarantees that after any trade, the product of the new reserves remains at least as large as the initial product, ensuring that swaps cannot drain liquidity from the pool. - -Rearranging this condition, we can express the invariant as a lower bound for $y$: - -\begin{equation} - y \geq \frac{x_0 y_0}{x}. -\end{equation} - -This means that for any valid trade, the resulting reserve state must lie on or above the AMM curve. - -\subsubsection{Extending the invariant to EulerSwap} - -For EulerSwap, we apply a similar principle. Given any reserve state $(x, y)$, we check whether it satisfies an equivalent invariant condition. - -From equation \eqref{eq:EulerSwap-1}, for values where \( 0 < x < x_0 \), the AMM curve constraint requires: - -\begin{equation} - \label{eq:invariant-x1} - y \geq y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-x\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{x}\right)\right). -\end{equation} - -For values where \( x > x_0 \), we could derive a similar condition for $y$ from equation \eqref{eq:EulerSwap-2}. However, a simpler and computationally cheaper approach is to use the inverse equation \eqref{eq:EulerSwap-3-inverse}, which defines the lower bound for $x$ instead: - -\begin{equation} - \label{eq:invariant-x2} - x \geq x_{0}+\frac{p_{y}}{p_{x}}\left(y_{0}-y\right)\left(c_{y}+\left(1-c_{y}\right)\left(\frac{y_{0}}{y}\right)\right). -\end{equation} - -These conditions together define the valid liquidity states in EulerSwap, ensuring that the AMM remains balanced while allowing for greater flexibility in liquidity provisioning. - -\section{Disclaimer} - -This paper is for general information purposes only. It does not constitute investment -advice or a recommendation or solicitation to buy or sell any investment and should not -be used in the evaluation of the merits of making any investment decision. It should not -be relied upon for accounting, legal or tax advice or investment recommendations. This -paper reflects current opinions of the authors and is not made on behalf of Euler Labs or its -affiliates and does not necessarily reflect the opinions of Euler Labs, its affiliates or individuals -associated with Euler Labs. The opinions reflected herein are subject to change without being -updated. - -\end{document} \ No newline at end of file diff --git a/docs/white-paper/references.bib b/docs/white-paper/references.bib deleted file mode 100644 index 11b9ea5..0000000 --- a/docs/white-paper/references.bib +++ /dev/null @@ -1,91 +0,0 @@ -@article{curvev2, - author = "Michael Egorov", - title = "Automatic market-making with dynamic peg", - journal = "", - volume = "", - number = "", - pages = "", - year = "2021", - DOI = "https://classic.curve.fi/files/crypto-pools-paper.pdf", - keywords = "amm" -} -@article{curvev1, - author = "Michael Egorov", - title = "StableSwap - efficient mechanism for Stablecoin liquidity", - journal = "", - volume = "", - number = "", - pages = "", - year = "2019", - DOI = "https://berkeley-defi.github.io/assets/material/StableSwap.pdf", - keywords = "amm" -} -@article{homotopy, - doi = {10.48550/ARXIV.2203.12123}, - - url = {https://arxiv.org/abs/2203.12123}, - - author = {Port, Alexander and Tiruviluamala, Neelesh}, - - keywords = {Trading and Market Microstructure (q-fin.TR), FOS: Economics and business, FOS: Economics and business, 91B26}, - - title = {Mixing Constant Sum and Constant Product Market Makers}, - - publisher = {arXiv}, - - year = {2022}, - - copyright = {Creative Commons Attribution 4.0 International} -} -@article{universalamm, - author = "Robinson, Dan", - title = "Uniswap v3: The Universal AMM", - journal = "", - volume = "", - number = "", - pages = "", - year = "2021", - DOI = "https://www.paradigm.xyz/2021/06/uniswap-v3-the-universal-amm", - keywords = "amm" -} - -@article{uniswapv2, - author = "Adams, Hayden, and Zinsmeister, Noah and Robinson, Dan", - title = "Uniswap v2 Core", - journal = "", - volume = "", - number = "", - pages = "", - year = "2020", - DOI = "https://uniswap.org/whitepaper.pdf", - keywords = "amm" -} -@article{uniswapv3, - author = "Adams, Hayden, and Keefer, River and Zinsmeister, Noah and Salem, Moody and Robinson, Dan", - title = "Uniswap v3 Core", - journal = "", - volume = "", - number = "", - pages = "", - year = "2022", - DOI = "https://uniswap.org/whitepaper-v3.pdf", - keywords = "amm" -} - -@article{uniswapv3vscurvev2, - author = "Reucassel, Duncan and Ong, Jeremy and 0xDEF1", - title = "Uniswap vs Curve: Which Is the Best DEX?", - journal = "", - volume = "", - number = "", - pages = "", - year = "2022", - DOI = "https://members.delphidigital.io/reports/uniswap-vs-curve-which-is-the-best-dex/#conclusion", - keywords = "amm" -} - - - - - -https://www.bis.org/publ/work955.pdf \ No newline at end of file From 873c04568fffbaf32fa60c3f734baf43d341382e Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 2 Mar 2025 12:27:08 +0000 Subject: [PATCH 153/312] feat: add fuzzland audit --- audits/eulerswap-audit-report.pdf | Bin 0 -> 426784 bytes lib/openzeppelin-contracts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 audits/eulerswap-audit-report.pdf diff --git a/audits/eulerswap-audit-report.pdf b/audits/eulerswap-audit-report.pdf new file mode 100644 index 0000000000000000000000000000000000000000..486f1f7b123d447a04f4e6c355e4df03e6339b63 GIT binary patch literal 426784 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%0A5Z*VDzMVN^>`j;@D>d+H*7o;o7 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 diff --git a/docs/whitepaper/main.tex b/docs/whitepaper/main.tex index b7b443f..1ac4e24 100644 --- a/docs/whitepaper/main.tex +++ b/docs/whitepaper/main.tex @@ -40,7 +40,7 @@ \maketitle \begin{abstract} -EulerSwap is an automated market maker (AMM) that integrates with Euler credit vaults to provide deeper liquidity for swaps. When a user initiates a swap, a smart contract called an EulerSwap borrows the required output token using the input token as collateral. This model enables up to 40x the liquidity depth of traditional AMMs by making idle assets in Euler more efficient. Unlike traditional AMMs, which often fragment liquidity across multiple pools, EulerSwap further increases capital efficiency by allowing a single, cross-collateralised credit vault to support multiple asset pairs at once. At its core, EulerSwap uses a flexible AMM curve to optimise swap pricing, ensuring deep liquidity while maintaining market balance. By combining just-in-time liquidity, shared liquidity across pools, and customisable AMM mechanics, EulerSwap reduces inefficiencies in liquidity provision, offering deeper markets, lower costs, and greater control for liquidity providers. +EulerSwap is an automated market maker (AMM) that integrates with Euler credit vaults to provide deeper liquidity for swaps. When a user initiates a swap, a smart contract called an EulerSwap operator borrows the required output token using the input token as collateral. This model enables up to 40x the liquidity depth of traditional AMMs by making idle assets in Euler more efficient. Unlike traditional AMMs, which often fragment liquidity across multiple pools, EulerSwap further increases capital efficiency by allowing a single, cross-collateralised credit vault to support multiple asset pairs at once. At its core, EulerSwap uses a flexible AMM curve to optimise swap pricing, ensuring deep liquidity while maintaining market balance. By combining just-in-time liquidity, shared liquidity across pools, and customisable AMM mechanics, EulerSwap reduces inefficiencies in liquidity provision, offering deeper markets, lower costs, and greater control for liquidity providers. \end{abstract} \section{Introduction} From d3ffcf63b738e1db6ad639fef1cbd2396956c8a6 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Mon, 3 Mar 2025 09:16:47 +0000 Subject: [PATCH 163/312] feat: install uniswap v4-core as submodule --- .gitmodules | 6 ++++++ lib/v4-core | 1 + remappings.txt | 3 ++- src/EulerSwapPeriphery.sol | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) create mode 160000 lib/v4-core diff --git a/.gitmodules b/.gitmodules index 7e69f48..18f0d8d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,9 @@ [submodule "lib/ethereum-vault-connector"] path = lib/ethereum-vault-connector url = https://github.com/euler-xyz/ethereum-vault-connector +[submodule "lib/lib/v4-core"] + path = lib/lib/v4-core + url = https://github.com/Uniswap/v4-core.git +[submodule "lib/v4-core"] + path = lib/v4-core + url = https://github.com/Uniswap/v4-core.git diff --git a/lib/v4-core b/lib/v4-core new file mode 160000 index 0000000..80311e3 --- /dev/null +++ b/lib/v4-core @@ -0,0 +1 @@ +Subproject commit 80311e34080fee64b6fc6c916e9a51a437d0e482 diff --git a/remappings.txt b/remappings.txt index 56ee1ca..6f94871 100644 --- a/remappings.txt +++ b/remappings.txt @@ -3,4 +3,5 @@ evc/=lib/ethereum-vault-connector/src/ evk/=lib/euler-vault-kit/src/ ethereum-vault-connector/=lib/ethereum-vault-connector/src/ evk-test/=lib/euler-vault-kit/test/ -permit2/=lib/euler-vault-kit/lib/permit2/ \ No newline at end of file +permit2/=lib/euler-vault-kit/lib/permit2/ +@uniswap/v4-core/=lib/v4-core/src/ diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index 7adf97d..aa7965c 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -5,6 +5,7 @@ import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; import {IEulerSwapPeriphery} from "./interfaces/IEulerSwapPeriphery.sol"; import {IERC20, IEulerSwap, SafeERC20} from "./EulerSwap.sol"; +import "@uniswap/v4-core/libraries/FullMath.sol"; contract EulerSwapPeriphery is IEulerSwapPeriphery { using SafeERC20 for IERC20; From 642408ad5d715e201749fa08f2da5f1d3487e36f Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Mon, 3 Mar 2025 09:23:41 +0000 Subject: [PATCH 164/312] feat: add fInverse() function to periphery --- src/EulerSwapPeriphery.sol | 55 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index aa7965c..ea39602 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -5,6 +5,7 @@ import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; import {IEulerSwapPeriphery} from "./interfaces/IEulerSwapPeriphery.sol"; import {IERC20, IEulerSwap, SafeERC20} from "./EulerSwap.sol"; +import {Math} from "openzeppelin-contracts/utils/math/Math.sol"; import "@uniswap/v4-core/libraries/FullMath.sol"; contract EulerSwapPeriphery is IEulerSwapPeriphery { @@ -189,4 +190,58 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { else output = uint256(dy); } } + + /** + * @notice Computes the inverse of the `f()` function for the EulerSwap liquidity curve. + * @dev Solves for `x` given `y` using the quadratic formula derived from the liquidity curve: + * x = (-b + sqrt(b^2 + 4ac)) / 2a + * Utilises Uniswap's FullMath to avoid overflow and ensures precision with upward rounding. + * + * @param y The y-coordinate input value (must be greater than `y0`). + * @param px Price factor for the x-axis (scaled by 1e18, between 1e18 and 1e36). + * @param py Price factor for the y-axis (scaled by 1e18, between 1e18 and 1e36). + * @param x0 Reference x-value on the liquidity curve (≤ 2^112 - 1). + * @param y0 Reference y-value on the liquidity curve (≤ 2^112 - 1). + * @param c Curve parameter shaping liquidity concentration (scaled by 1e18, between 0 and 1e18). + * + * @return x The computed x-coordinate on the liquidity curve. + * + * @custom:precision Uses rounding up to maintain precision in all calculations. + * @custom:safety FullMath handles potential overflow in the b^2 computation. + * @custom:requirement Input `y` must be strictly greater than `y0`; otherwise, the function will revert. + */ + function fInverse(uint256 y, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) + public + pure + returns (uint256) + { + // A component of the quadratic formula: a = 2 * c + uint256 A = 2 * c; + + // B component of the quadratic formula + int256 B = int256((px * (y - y0) + py - 1) / py) - int256((x0 * (2 * c - 1e18) + 1e18 - 1) / 1e18); + + // B^2 component, using FullMath for overflow safety + uint256 absB = B < 0 ? uint256(-B) : uint256(B); + uint256 squaredB = FullMath.mulDiv(absB, absB, 1e18) + (absB * absB % 1e18 == 0 ? 0 : 1); + + // 4 * A * C component of the quadratic formula + uint256 AC4 = Math.mulDiv( + Math.mulDiv(4 * c, (1e18 - c), 1e18, Math.Rounding.Ceil), + Math.mulDiv(x0, x0, 1e18, Math.Rounding.Ceil), + 1e18, + Math.Rounding.Ceil + ); + + // Discriminant: b^2 + 4ac, scaled up to maintain precision + uint256 discriminant = (squaredB + AC4) * 1e18; + + // Square root of the discriminant (rounded up) + uint256 sqrt = Math.sqrt(discriminant); + sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; + + // Compute and return x = fInverse(y) using the quadratic formula + return Math.mulDiv(uint256(int256(sqrt) - B), 1e18, A, Math.Rounding.Ceil); + } + } From 823eeac743ba0eba9a9ea416a8a4bd6a6c500bd2 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Mon, 3 Mar 2025 10:02:17 +0000 Subject: [PATCH 165/312] feat: add fInverse() test and EulerSwapMock.sol contract --- test/EulerSwapPeriphery.t.sol | 27 ++++++++++++++++++++++++++- test/mocks/EulerSwapMock.sol | 23 +++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 test/mocks/EulerSwapMock.sol diff --git a/test/EulerSwapPeriphery.t.sol b/test/EulerSwapPeriphery.t.sol index 7e6f594..9a77938 100644 --- a/test/EulerSwapPeriphery.t.sol +++ b/test/EulerSwapPeriphery.t.sol @@ -1,15 +1,27 @@ // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.24; -import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery} from "./EulerSwapTestBase.t.sol"; +import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol"; +import {EulerSwapMock} from "./mocks/EulerSwapMock.sol"; contract EulerSwapPeripheryTest is EulerSwapTestBase { EulerSwap public eulerSwap; + EulerSwapMock public eulerSwapMock; function setUp() public virtual override { super.setUp(); eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + + IEulerSwap.Params memory params = getEulerSwapParams(50e18, 50e18, 0.4e18); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams({ + priceX: 1e18, + priceY: 1e18, + concentrationX: 0.85e18, + concentrationY: 0.85e18 + }); + + eulerSwapMock = new EulerSwapMock(params, curveParams); // Use the mock EulerSwap contract with a public f() function } function test_SwapExactIn() public { @@ -69,4 +81,17 @@ contract EulerSwapPeripheryTest is EulerSwapTestBase { periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut * 2, amountIn); vm.stopPrank(); } + + function test_fInverseFuzz(uint256 x) public { + x = bound(x, 2, 50e18 - 1); // it fails if 1 us used, not an issue since only used in periphery + uint256 y = eulerSwapMock.exposedF(x, 1e18, 1e18, 50e18, 50e18, 0.85e18); + uint256 outX = periphery.fInverse(y, 1e18, 1e18, 50e18, 50e18, 0.85e18); + + // Ensure x is within the expected range + assertGe(outX, x); // Asserts xOut >= x + assertLe(outX, x + 1); // Asserts xOut <= x + 1 + + // Alternative using assertApproxEqAbs for absolute difference within 1 + assertApproxEqAbs(x, outX, 1); + } } diff --git a/test/mocks/EulerSwapMock.sol b/test/mocks/EulerSwapMock.sol new file mode 100644 index 0000000..4f42094 --- /dev/null +++ b/test/mocks/EulerSwapMock.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +import {EulerSwap, IEulerSwap} from "../../src/EulerSwap.sol"; + +contract EulerSwapMock is EulerSwap { + + constructor(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams) + EulerSwap(params, curveParams) + {} + + /// @notice Exposes the internal f() function as a public function for testing + function exposedF( + uint256 x, + uint256 px, + uint256 py, + uint256 x0, + uint256 y0, + uint256 c + ) external pure returns (uint256) { + return f(x, px, py, x0, y0, c); + } +} From d47ea30402015f392a18b573738e7c178e030816 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Mon, 3 Mar 2025 11:15:30 +0000 Subject: [PATCH 166/312] chore: rename mock to harness and forge fmt --- .gitmodules | 5 +---- src/EulerSwapPeriphery.sol | 1 - test/EulerSwapPeriphery.t.sol | 22 ++++++++----------- .../EulerSwapHarness.sol} | 20 +++++++---------- 4 files changed, 18 insertions(+), 30 deletions(-) rename test/{mocks/EulerSwapMock.sol => harness/EulerSwapHarness.sol} (52%) diff --git a/.gitmodules b/.gitmodules index 18f0d8d..95173f0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,7 +12,4 @@ url = https://github.com/euler-xyz/ethereum-vault-connector [submodule "lib/lib/v4-core"] path = lib/lib/v4-core - url = https://github.com/Uniswap/v4-core.git -[submodule "lib/v4-core"] - path = lib/v4-core - url = https://github.com/Uniswap/v4-core.git + url = https://github.com/Uniswap/v4-core.git \ No newline at end of file diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index ea39602..af28f6d 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -243,5 +243,4 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { // Compute and return x = fInverse(y) using the quadratic formula return Math.mulDiv(uint256(int256(sqrt) - B), 1e18, A, Math.Rounding.Ceil); } - } diff --git a/test/EulerSwapPeriphery.t.sol b/test/EulerSwapPeriphery.t.sol index 9a77938..a771715 100644 --- a/test/EulerSwapPeriphery.t.sol +++ b/test/EulerSwapPeriphery.t.sol @@ -2,11 +2,11 @@ pragma solidity ^0.8.24; import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol"; -import {EulerSwapMock} from "./mocks/EulerSwapMock.sol"; +import {EulerSwapHarness} from "./harness/EulerSwapHarness.sol"; contract EulerSwapPeripheryTest is EulerSwapTestBase { EulerSwap public eulerSwap; - EulerSwapMock public eulerSwapMock; + EulerSwapHarness public eulerSwapHarness; function setUp() public virtual override { super.setUp(); @@ -14,14 +14,10 @@ contract EulerSwapPeripheryTest is EulerSwapTestBase { eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); IEulerSwap.Params memory params = getEulerSwapParams(50e18, 50e18, 0.4e18); - IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams({ - priceX: 1e18, - priceY: 1e18, - concentrationX: 0.85e18, - concentrationY: 0.85e18 - }); - - eulerSwapMock = new EulerSwapMock(params, curveParams); // Use the mock EulerSwap contract with a public f() function + IEulerSwap.CurveParams memory curveParams = + IEulerSwap.CurveParams({priceX: 1e18, priceY: 1e18, concentrationX: 0.85e18, concentrationY: 0.85e18}); + + eulerSwapHarness = new EulerSwapHarness(params, curveParams); // Use the mock EulerSwap contract with a public f() function } function test_SwapExactIn() public { @@ -82,9 +78,9 @@ contract EulerSwapPeripheryTest is EulerSwapTestBase { vm.stopPrank(); } - function test_fInverseFuzz(uint256 x) public { - x = bound(x, 2, 50e18 - 1); // it fails if 1 us used, not an issue since only used in periphery - uint256 y = eulerSwapMock.exposedF(x, 1e18, 1e18, 50e18, 50e18, 0.85e18); + function test_fInverseFuzz(uint256 x) public view { + x = bound(x, 2, 50e18 - 1); // note that it fails if 1 used as minimum, not an issue since only used in periphery + uint256 y = eulerSwapHarness.exposedF(x, 1e18, 1e18, 50e18, 50e18, 0.85e18); uint256 outX = periphery.fInverse(y, 1e18, 1e18, 50e18, 50e18, 0.85e18); // Ensure x is within the expected range diff --git a/test/mocks/EulerSwapMock.sol b/test/harness/EulerSwapHarness.sol similarity index 52% rename from test/mocks/EulerSwapMock.sol rename to test/harness/EulerSwapHarness.sol index 4f42094..88801d0 100644 --- a/test/mocks/EulerSwapMock.sol +++ b/test/harness/EulerSwapHarness.sol @@ -3,21 +3,17 @@ pragma solidity ^0.8.27; import {EulerSwap, IEulerSwap} from "../../src/EulerSwap.sol"; -contract EulerSwapMock is EulerSwap { - - constructor(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams) - EulerSwap(params, curveParams) +contract EulerSwapHarness is EulerSwap { + constructor(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams) + EulerSwap(params, curveParams) {} /// @notice Exposes the internal f() function as a public function for testing - function exposedF( - uint256 x, - uint256 px, - uint256 py, - uint256 x0, - uint256 y0, - uint256 c - ) external pure returns (uint256) { + function exposedF(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) + external + pure + returns (uint256) + { return f(x, px, py, x0, y0, c); } } From 99ecaa3a03e1cecf5c98b8da6aaa95f5460daa41 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Mon, 3 Mar 2025 11:56:16 +0000 Subject: [PATCH 167/312] chore: fInverse() external instead of public --- src/EulerSwapPeriphery.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index af28f6d..da57042 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -211,7 +211,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { * @custom:requirement Input `y` must be strictly greater than `y0`; otherwise, the function will revert. */ function fInverse(uint256 y, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) - public + external pure returns (uint256) { From 08724a953241e0c882bde0377cdc89b8e6d89d92 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 3 Mar 2025 20:59:53 +0900 Subject: [PATCH 168/312] fix: gitmodules --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 95173f0..b887c1e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,4 +12,4 @@ url = https://github.com/euler-xyz/ethereum-vault-connector [submodule "lib/lib/v4-core"] path = lib/lib/v4-core - url = https://github.com/Uniswap/v4-core.git \ No newline at end of file + url = https://github.com/Uniswap/v4-core \ No newline at end of file From 045b2061077ea1d68fb4cba5d59b0032bbe813ce Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 3 Mar 2025 21:01:09 +0900 Subject: [PATCH 169/312] fix: gitmodules --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index b887c1e..e42a107 100644 --- a/.gitmodules +++ b/.gitmodules @@ -11,5 +11,5 @@ path = lib/ethereum-vault-connector url = https://github.com/euler-xyz/ethereum-vault-connector [submodule "lib/lib/v4-core"] - path = lib/lib/v4-core + path = lib/v4-core url = https://github.com/Uniswap/v4-core \ No newline at end of file From 7d59efaf1b1ddeeca848ce597f4d2825a84dd789 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 3 Mar 2025 21:01:24 +0900 Subject: [PATCH 170/312] fix: gitmodules --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index e42a107..a04a750 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,6 +10,6 @@ [submodule "lib/ethereum-vault-connector"] path = lib/ethereum-vault-connector url = https://github.com/euler-xyz/ethereum-vault-connector -[submodule "lib/lib/v4-core"] +[submodule "lib/v4-core"] path = lib/v4-core url = https://github.com/Uniswap/v4-core \ No newline at end of file From 4e7aa22b0041de0c58a5abd9eb4a3c69f7f0b333 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 3 Mar 2025 21:48:54 +0900 Subject: [PATCH 171/312] Add pool's address in Swap event --- .gitignore | 1 + src/EulerSwap.sol | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 64c78d5..6c7f350 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ out/ !/broadcast /broadcast/*/31337/ /broadcast/**/dry-run/ +broadcast/ # Dotenv file .env diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index a9e3695..c478e5c 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -38,6 +38,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { event EulerSwapCreated(address indexed asset0, address indexed asset1); event Swap( + address pool, address indexed sender, uint256 amount0In, uint256 amount1In, @@ -135,6 +136,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { reserve1 = uint112(newReserve1); emit Swap( + address(this), _msgSender(), amount0In, amount1In, From f558c74922d1774dbd6bb7e6b0b1ad9bbdd70dc2 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 3 Mar 2025 20:09:32 +0700 Subject: [PATCH 172/312] Revert "Add pool's address in Swap event" --- .gitignore | 1 - src/EulerSwap.sol | 2 -- 2 files changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 6c7f350..64c78d5 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ out/ !/broadcast /broadcast/*/31337/ /broadcast/**/dry-run/ -broadcast/ # Dotenv file .env diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index c478e5c..a9e3695 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -38,7 +38,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { event EulerSwapCreated(address indexed asset0, address indexed asset1); event Swap( - address pool, address indexed sender, uint256 amount0In, uint256 amount1In, @@ -136,7 +135,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { reserve1 = uint112(newReserve1); emit Swap( - address(this), _msgSender(), amount0In, amount1In, From b2112f4fd2703babc1884855bde0b1f5ce98ba0e Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 3 Mar 2025 09:55:18 -0500 Subject: [PATCH 173/312] use OZ's mulDiv instead of Uniswap's --- .gitmodules | 3 --- lib/v4-core | 1 - remappings.txt | 1 - src/EulerSwapPeriphery.sol | 5 ++--- 4 files changed, 2 insertions(+), 8 deletions(-) delete mode 160000 lib/v4-core diff --git a/.gitmodules b/.gitmodules index a04a750..7e69f48 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,6 +10,3 @@ [submodule "lib/ethereum-vault-connector"] path = lib/ethereum-vault-connector url = https://github.com/euler-xyz/ethereum-vault-connector -[submodule "lib/v4-core"] - path = lib/v4-core - url = https://github.com/Uniswap/v4-core \ No newline at end of file diff --git a/lib/v4-core b/lib/v4-core deleted file mode 160000 index 80311e3..0000000 --- a/lib/v4-core +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 80311e34080fee64b6fc6c916e9a51a437d0e482 diff --git a/remappings.txt b/remappings.txt index 6f94871..d217abb 100644 --- a/remappings.txt +++ b/remappings.txt @@ -4,4 +4,3 @@ evk/=lib/euler-vault-kit/src/ ethereum-vault-connector/=lib/ethereum-vault-connector/src/ evk-test/=lib/euler-vault-kit/test/ permit2/=lib/euler-vault-kit/lib/permit2/ -@uniswap/v4-core/=lib/v4-core/src/ diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index da57042..f6da632 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -6,7 +6,6 @@ import {IEVault} from "evk/EVault/IEVault.sol"; import {IEulerSwapPeriphery} from "./interfaces/IEulerSwapPeriphery.sol"; import {IERC20, IEulerSwap, SafeERC20} from "./EulerSwap.sol"; import {Math} from "openzeppelin-contracts/utils/math/Math.sol"; -import "@uniswap/v4-core/libraries/FullMath.sol"; contract EulerSwapPeriphery is IEulerSwapPeriphery { using SafeERC20 for IERC20; @@ -195,7 +194,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { * @notice Computes the inverse of the `f()` function for the EulerSwap liquidity curve. * @dev Solves for `x` given `y` using the quadratic formula derived from the liquidity curve: * x = (-b + sqrt(b^2 + 4ac)) / 2a - * Utilises Uniswap's FullMath to avoid overflow and ensures precision with upward rounding. + * Utilises mulDiv to avoid overflow and ensures precision with upward rounding. * * @param y The y-coordinate input value (must be greater than `y0`). * @param px Price factor for the x-axis (scaled by 1e18, between 1e18 and 1e36). @@ -223,7 +222,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { // B^2 component, using FullMath for overflow safety uint256 absB = B < 0 ? uint256(-B) : uint256(B); - uint256 squaredB = FullMath.mulDiv(absB, absB, 1e18) + (absB * absB % 1e18 == 0 ? 0 : 1); + uint256 squaredB = Math.mulDiv(absB, absB, 1e18, Math.Rounding.Ceil); // 4 * A * C component of the quadratic formula uint256 AC4 = Math.mulDiv( From b9a146ac6a8faf2e955791915d662e2bee8c1011 Mon Sep 17 00:00:00 2001 From: erik1o6 <2449138+erik1o6@users.noreply.github.com> Date: Mon, 3 Mar 2025 17:54:52 +0100 Subject: [PATCH 174/312] docs: update SECURITY.md with vulnerability disclosure policy Signed-off-by: erik1o6 <2449138+erik1o6@users.noreply.github.com> --- SECURITY.md | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 18e743c..d38e22b 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,8 +1,25 @@ -# Security policy +# Euler Security Policy -## Reporting a vulnerability +## Vulnerability Disclosure and Bug Bounty -If you discover a security vulnerability, please report it responsibly. Do not publicly disclose the issue until your report has been addressed. Resources for reporting: +Security is a top priority at Euler, and we engage in regular security reviews and have an active bug bounty program to ensure the integrity of our systems. -- **Email:** security@euler.xyz -- **Further reading:** https://docs.euler.finance/security/overview +To report a vulnerability, **please submit it through our bug bounty program**: +[Euler Bug Bounty](https://euler.finance/bug-bounty) + +**Reports sent via email will not be accepted.** Email should only be used for general security inquiries. + +## Security Team Contact Details + +For security-related questions or inquiries (not vulnerability reports), you can contact us via: +- **Email**: [security@euler.xyz](mailto:security@euler.xyz) +- **PGP Encryption**: [Euler Public Key](https://euler.finance/.well-known/public-key.asc) + +## Previous Security Reviews + +Euler undergoes regular security audits. You can find details of previous security reviews here: +[Euler Security Reviews](https://docs.euler.finance/security/security-reviews) + +## Preferred Languages + +We accept security-related inquiries in **English (en)** From 9e67c0ce024e24c0ff2dc1cb78c53d66505ab896 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 3 Mar 2025 09:08:15 -0500 Subject: [PATCH 175/312] pass in raw values for initial and current reserves - offsetReserve is not flexible enough for all use-cases: Instead we can do this in the hub/factory --- docs/interfaces.md | 12 ++++---- src/EulerSwap.sol | 51 +++++++++++++++------------------ src/interfaces/IEulerSwap.sol | 10 ++++--- test/AltDecimals.t.sol | 8 +++--- test/DepositFailures.t.sol | 2 +- test/EulerSwapFactoryTest.t.sol | 9 ++++-- test/EulerSwapPeriphery.t.sol | 2 +- test/EulerSwapTest.t.sol | 8 +++--- test/EulerSwapTestBase.t.sol | 8 ++++-- test/PreserveNav.t.sol | 2 +- test/UniswapV2Call.t.sol | 2 +- 11 files changed, 58 insertions(+), 56 deletions(-) diff --git a/docs/interfaces.md b/docs/interfaces.md index a69724f..f06898a 100644 --- a/docs/interfaces.md +++ b/docs/interfaces.md @@ -46,13 +46,13 @@ The `IEulerSwap` interface defines the core functionality for executing token sw - **description**: Returns the address of the account managing EulerSwap. -#### `initialReserve0() external view returns (uint112);` +#### `equilibriumReserve0() external view returns (uint112);` -- **description**: Returns the initial reserve amount of asset 0. +- **description**: Returns the equilibrium reserve amount of asset 0. -#### `initialReserve1() external view returns (uint112);` +#### `equilibriumReserve1() external view returns (uint112);` -- **description**: Returns the initial reserve amount of asset 1. +- **description**: Returns the equilibrium reserve amount of asset 1. #### `feeMultiplier() external view returns (uint256);` @@ -66,11 +66,11 @@ The `IEulerSwap` interface defines the core functionality for executing token sw #### `priceX() external view returns (uint256);` -- **description**: Returns the price of asset X in terms of asset Y. +- **description**: Returns the marginal price of asset X in terms of asset Y at the equilibrium point. #### `priceY() external view returns (uint256);` -- **description**: Returns the price of asset Y in terms of asset X. +- **description**: Returns the marginal price of asset Y in terms of asset X at the equilibrium point. #### `concentrationX() external view returns (uint256);` diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index a9e3695..19e0ea7 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -21,10 +21,8 @@ contract EulerSwap is IEulerSwap, EVCUtil { address public immutable asset0; address public immutable asset1; address public immutable eulerAccount; - uint112 public immutable debtLimit0; - uint112 public immutable debtLimit1; - uint112 public immutable initialReserve0; - uint112 public immutable initialReserve1; + uint112 public immutable equilibriumReserve0; + uint112 public immutable equilibriumReserve1; uint256 public immutable feeMultiplier; uint256 public immutable priceX; @@ -68,7 +66,11 @@ contract EulerSwap is IEulerSwap, EVCUtil { // EulerSwap params require(params.fee < 1e18, BadParam()); - require(params.debtLimit0 <= type(uint112).max && params.debtLimit1 <= type(uint112).max, BadParam()); + require( + params.equilibriumReserve0 <= type(uint112).max && params.equilibriumReserve1 <= type(uint112).max, + BadParam() + ); + require(params.currReserve0 <= type(uint112).max && params.currReserve1 <= type(uint112).max, BadParam()); require(curveParams.priceX > 0 && curveParams.priceY > 0, BadParam()); require(curveParams.priceX <= 1e36 && curveParams.priceY <= 1e36, BadParam()); require(curveParams.concentrationX <= 1e18 && curveParams.concentrationY <= 1e18, BadParam()); @@ -83,10 +85,10 @@ contract EulerSwap is IEulerSwap, EVCUtil { asset0 = asset0Addr; asset1 = asset1Addr; eulerAccount = params.eulerAccount; - debtLimit0 = params.debtLimit0; - debtLimit1 = params.debtLimit1; - initialReserve0 = reserve0 = offsetReserve(params.debtLimit0, params.vault0); - initialReserve1 = reserve1 = offsetReserve(params.debtLimit1, params.vault1); + equilibriumReserve0 = params.equilibriumReserve0; + equilibriumReserve1 = params.equilibriumReserve1; + reserve0 = params.currReserve0; + reserve1 = params.currReserve1; feeMultiplier = 1e18 - params.fee; // Curve params @@ -96,6 +98,11 @@ contract EulerSwap is IEulerSwap, EVCUtil { concentrationX = curveParams.concentrationX; concentrationY = curveParams.concentrationY; + // Validate reserves + + require(verify(reserve0, reserve1), CurveViolation()); + require(!verify(reserve0 > 0 ? reserve0 - 1 : 0, reserve1 > 0 ? reserve1 - 1 : 0), CurveViolation()); + emit EulerSwapCreated(asset0Addr, asset1Addr); } @@ -184,12 +191,14 @@ contract EulerSwap is IEulerSwap, EVCUtil { /// @inheritdoc IEulerSwap function verify(uint256 newReserve0, uint256 newReserve1) public view returns (bool) { - if (newReserve0 >= initialReserve0) { - if (newReserve1 >= initialReserve1) return true; - return newReserve0 >= f(newReserve1, priceY, priceX, initialReserve1, initialReserve0, concentrationY); + if (newReserve0 >= equilibriumReserve0) { + if (newReserve1 >= equilibriumReserve1) return true; + return + newReserve0 >= f(newReserve1, priceY, priceX, equilibriumReserve1, equilibriumReserve0, concentrationY); } else { - if (newReserve1 < initialReserve1) return false; - return newReserve1 >= f(newReserve0, priceX, priceY, initialReserve0, initialReserve1, concentrationX); + if (newReserve1 < equilibriumReserve1) return false; + return + newReserve1 >= f(newReserve0, priceX, priceY, equilibriumReserve0, equilibriumReserve1, concentrationX); } } @@ -237,20 +246,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { return shares == 0 ? 0 : IEVault(vault).convertToAssets(shares); } - function offsetReserve(uint112 reserve, address vault) internal view returns (uint112) { - uint256 offset; - uint256 debt = myDebt(vault); - - if (debt != 0) { - offset = reserve > debt ? reserve - debt : 0; - } else { - offset = reserve + myBalance(vault); - } - - require(offset <= type(uint112).max, Overflow()); - return uint112(offset); - } - /// @dev EulerSwap curve definition /// Pre-conditions: x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 function f(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { diff --git a/src/interfaces/IEulerSwap.sol b/src/interfaces/IEulerSwap.sol index 1ad0676..535ba03 100644 --- a/src/interfaces/IEulerSwap.sol +++ b/src/interfaces/IEulerSwap.sol @@ -6,8 +6,10 @@ interface IEulerSwap { address vault0; address vault1; address eulerAccount; - uint112 debtLimit0; - uint112 debtLimit1; + uint112 equilibriumReserve0; + uint112 equilibriumReserve1; + uint112 currReserve0; + uint112 currReserve1; uint256 fee; } @@ -46,8 +48,8 @@ interface IEulerSwap { function asset0() external view returns (address); function asset1() external view returns (address); function eulerAccount() external view returns (address); - function initialReserve0() external view returns (uint112); - function initialReserve1() external view returns (uint112); + function equilibriumReserve0() external view returns (uint112); + function equilibriumReserve1() external view returns (uint112); function feeMultiplier() external view returns (uint256); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 status); diff --git a/test/AltDecimals.t.sol b/test/AltDecimals.t.sol index 9079885..d8eff6c 100644 --- a/test/AltDecimals.t.sol +++ b/test/AltDecimals.t.sol @@ -11,7 +11,7 @@ contract AltDecimals is EulerSwapTestBase { } function test_alt_decimals_6_18_in() public { - eulerSwap = createEulerSwap(50e6, 50e18, 0, 1e18, 1e6, 0.9e18, 0.9e18); + eulerSwap = createEulerSwap(50e6, 60e18, 0, 1e18, 1e6, 0.9e18, 0.9e18); skimAll(eulerSwap, true); uint256 amount = 1e6; @@ -31,7 +31,7 @@ contract AltDecimals is EulerSwapTestBase { } function test_alt_decimals_6_18_out() public { - eulerSwap = createEulerSwap(50e6, 50e18, 0, 1e18, 1e6, 0.9e18, 0.9e18); + eulerSwap = createEulerSwap(50e6, 60e18, 0, 1e18, 1e6, 0.9e18, 0.9e18); skimAll(eulerSwap, true); uint256 amount = 1e18; @@ -51,7 +51,7 @@ contract AltDecimals is EulerSwapTestBase { } function test_alt_decimals_18_6_in() public { - eulerSwap = createEulerSwap(50e18, 50e6, 0, 1e6, 1e18, 0.9e18, 0.9e18); + eulerSwap = createEulerSwap(60e18, 50e6, 0, 1e6, 1e18, 0.9e18, 0.9e18); skimAll(eulerSwap, true); uint256 amount = 1e18; @@ -71,7 +71,7 @@ contract AltDecimals is EulerSwapTestBase { } function test_alt_decimals_18_6_out() public { - eulerSwap = createEulerSwap(50e18, 50e6, 0, 1e6, 1e18, 0.9e18, 0.9e18); + eulerSwap = createEulerSwap(60e18, 50e6, 0, 1e6, 1e18, 0.9e18, 0.9e18); skimAll(eulerSwap, false); uint256 amount = 1e6; diff --git a/test/DepositFailures.t.sol b/test/DepositFailures.t.sol index 35d2e47..a0f93ed 100644 --- a/test/DepositFailures.t.sol +++ b/test/DepositFailures.t.sol @@ -13,7 +13,7 @@ contract DepositFailuresTest is EulerSwapTestBase { function setUp() public virtual override { super.setUp(); - eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + eulerSwap = createEulerSwap(60e18, 60e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); } function test_griefing() public monotonicHolderNAV { diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index b7fa719..bae4701 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -20,7 +20,8 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { uint256 allPoolsLengthBefore = eulerSwapFactory.allPoolsLength(); bytes32 salt = bytes32(uint256(1234)); - IEulerSwap.Params memory poolParams = IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 0); + IEulerSwap.Params memory poolParams = + IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 0); IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); address predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); @@ -73,7 +74,8 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { function testDeployWithAssetsOutOfOrderOrEqual() public { bytes32 salt = bytes32(uint256(1234)); - IEulerSwap.Params memory poolParams = IEulerSwap.Params(address(eTST), address(eTST), holder, 1e18, 1e18, 0); + IEulerSwap.Params memory poolParams = + IEulerSwap.Params(address(eTST), address(eTST), holder, 1e18, 1e18, 1e18, 1e18, 0); IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); vm.prank(holder); @@ -83,7 +85,8 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { function testDeployWithBadFee() public { bytes32 salt = bytes32(uint256(1234)); - IEulerSwap.Params memory poolParams = IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18); + IEulerSwap.Params memory poolParams = + IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 1e18); IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); vm.prank(holder); diff --git a/test/EulerSwapPeriphery.t.sol b/test/EulerSwapPeriphery.t.sol index a771715..036bc05 100644 --- a/test/EulerSwapPeriphery.t.sol +++ b/test/EulerSwapPeriphery.t.sol @@ -11,7 +11,7 @@ contract EulerSwapPeripheryTest is EulerSwapTestBase { function setUp() public virtual override { super.setUp(); - eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + eulerSwap = createEulerSwap(60e18, 60e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); IEulerSwap.Params memory params = getEulerSwapParams(50e18, 50e18, 0.4e18); IEulerSwap.CurveParams memory curveParams = diff --git a/test/EulerSwapTest.t.sol b/test/EulerSwapTest.t.sol index e08ae1b..c23917d 100644 --- a/test/EulerSwapTest.t.sol +++ b/test/EulerSwapTest.t.sol @@ -9,7 +9,7 @@ contract EulerSwapTest is EulerSwapTestBase { function setUp() public virtual override { super.setUp(); - eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + eulerSwap = createEulerSwap(60e18, 60e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); } function test_basicSwap_exactIn() public monotonicHolderNAV { @@ -49,7 +49,7 @@ contract EulerSwapTest is EulerSwapTestBase { int256 origNAV = getHolderNAV(); - eulerSwap = createEulerSwap(50e18, 50e18, 0, px, py, 0.4e18, 0.85e18); + eulerSwap = createEulerSwap(60e18, 60e18, 0, px, py, 0.4e18, 0.85e18); uint256 amountIn = 1e18; uint256 amountOut = @@ -102,7 +102,7 @@ contract EulerSwapTest is EulerSwapTestBase { oracle.setPrice(address(eTST), unitOfAccount, price); oracle.setPrice(address(assetTST), unitOfAccount, price); - eulerSwap = createEulerSwap(50e18, 50e18, 0, px, py, cx, cy); + eulerSwap = createEulerSwap(60e18, 60e18, 0, px, py, cx, cy); } int256 origNAV = getHolderNAV(); @@ -138,7 +138,7 @@ contract EulerSwapTest is EulerSwapTestBase { cy = bound(cy, 0.01e18, 0.99e18); fee = bound(fee, 0, 0.1e18); - eulerSwap = createEulerSwap(50e18, 50e18, fee, 1e18, 1e18, cx, cy); + eulerSwap = createEulerSwap(60e18, 60e18, fee, 1e18, 1e18, cx, cy); int256 origNAV = getHolderNAV(); diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index faf30e8..9c2d862 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -141,7 +141,7 @@ contract EulerSwapTestBase is EVaultTestBase { return skimmed; } - function getEulerSwapParams(uint112 debtLimitA, uint112 debtLimitB, uint256 fee) + function getEulerSwapParams(uint112 reserve0, uint112 reserve1, uint256 fee) internal view returns (EulerSwap.Params memory) @@ -150,8 +150,10 @@ contract EulerSwapTestBase is EVaultTestBase { vault0: address(eTST), vault1: address(eTST2), eulerAccount: holder, - debtLimit0: debtLimitA, - debtLimit1: debtLimitB, + equilibriumReserve0: reserve0, + equilibriumReserve1: reserve1, + currReserve0: reserve0, + currReserve1: reserve1, fee: fee }); } diff --git a/test/PreserveNav.t.sol b/test/PreserveNav.t.sol index dda6fd2..e4fab33 100644 --- a/test/PreserveNav.t.sol +++ b/test/PreserveNav.t.sol @@ -30,7 +30,7 @@ contract PreserveNav is EulerSwapTestBase { else fee -= 0.1e18; - eulerSwap = createEulerSwap(50e18, 50e18, fee, 1e18, 1e18, cx, cy); + eulerSwap = createEulerSwap(60e18, 60e18, fee, 1e18, 1e18, cx, cy); skimAll(eulerSwap, preSkimDir); int256 nav1 = getHolderNAV(); diff --git a/test/UniswapV2Call.t.sol b/test/UniswapV2Call.t.sol index 64bdd69..1d90ed6 100644 --- a/test/UniswapV2Call.t.sol +++ b/test/UniswapV2Call.t.sol @@ -11,7 +11,7 @@ contract UniswapV2CallTest is EulerSwapTestBase { function setUp() public virtual override { super.setUp(); - eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + eulerSwap = createEulerSwap(60e18, 60e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); swapCallback = new SwapCallbackTest(); } From 705d4e062a761be1694031167e14c6729ca561e0 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Tue, 4 Mar 2025 07:48:04 +0000 Subject: [PATCH 176/312] chore: update .gitignore --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 64c78d5..0983f65 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,8 @@ out/ .env # Coverage file -lcov.info \ No newline at end of file +lcov.info + +# MAC files +.DS_Store +__MACOSX \ No newline at end of file From 957d3b678bcbb8df69a9f081b5d267ebd48b6059 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Tue, 4 Mar 2025 07:44:10 +0000 Subject: [PATCH 177/312] chore: remove __MACOSX and .DS_Store files --- .DS_Store | Bin 6148 -> 0 bytes docs/.DS_Store | Bin 6148 -> 0 bytes docs/whitepaper/.DS_Store | Bin 6148 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store delete mode 100644 docs/.DS_Store delete mode 100644 docs/whitepaper/.DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index ca2b7874ee44cef1857d5487e8c8184223131c55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~F$w}f3`G;&La^D=avBfd4F=H@>;(h`8(BfodXDZ-CJ2t!BJu;tpJXO1`-+{7 zi0JxuSc&u^GJ~7S(n4d3ypw~RWiQwJa2ZeM@rat$Cvn!+@Lrnz*rt#G36KB@kN^q% z5COZlVY7KvMiL+a5_l4@??Zx{=Fn2rKOG1@0zf;I-LUpq0-CG<&7q|#Dlm=dL8DcD z46(YmLsOi~p`~hV7meXV4M3`}dgXhH(h?7~0-B+w9;*1Wg-e+&OK|2Hj6Nq_|Y zjDU8VVY9|d#ohY$dRE^>)z$?L_2URHKLJSWDqg_du%B!J&7q|#Dlq;CI0gn1_$q-1 D?w=C8 diff --git a/docs/.DS_Store b/docs/.DS_Store deleted file mode 100644 index 08a0f61b1e0fb0385acab587ef755650807e9ac3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK!AiqG5S?wSO(;SS3OxqAR;;!t;w8lT14i_qQWFwvFlI}ennNk%tUu(J_&v_- zZk19!co8WxF#Bd_XR_?uu(JyQ!kb1108Id}PzftGHs1)1lded`cnF31Mhtr}f&evM ziDt)tWPtXr0R;>pfgE@3YyZY!F&Txa3^C#@9Hq%5?{wZprCQtAtXp-fVcq#dS@?O7 zPbXe5zMN_Z{BuhCx;!hyGQf6ZSCytpI!_e)2B?nXi5eCeM+_rF5nf7A6ED5kF!)} z4;Zn?USu&c1Iz$3uqu()cuEA2HP6wf8#_yP!g?XU}H9Ptp6%NAH$SpI# z3@kHH)!io5|MQ>U|I10-V+NRkwPHZj`hMTTC7If~vN)=>4(dHB3B{EfKU2_9r5IzW d6t_^7px+?_(KT3VL=OsI1QZS2Fav+ezz1*-P5}S_ diff --git a/docs/whitepaper/.DS_Store b/docs/whitepaper/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Tue, 4 Mar 2025 08:27:12 +0000 Subject: [PATCH 178/312] feat: add detailed event documentation for EulerSwap and EulerSwapFactory contracts --- docs/events.md | 143 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 docs/events.md diff --git a/docs/events.md b/docs/events.md new file mode 100644 index 0000000..b660e3b --- /dev/null +++ b/docs/events.md @@ -0,0 +1,143 @@ +# Events + +## Introduction + +The EulerSwap smart contracts emit several key event types to notify off-chain systems (e.g., frontends, analytics tools) of important state changes. These events facilitate transparency, integration with external systems, and effective monitoring of the protocol's behavior. + +Events such as EulerSwapCreated and PoolDeployed are particularly useful for solvers and aggregators. These tools can track new pool creations, allowing them to dynamically update their routing algorithms and ensure trades are optimally routed through EulerSwap pools, enhancing liquidity and trading efficiency. + +### Summary + +| **Event** | **Contract** | **Purpose** | **Use Case** | +| ------------------ | ------------------ | ----------------------------------------------------- | ------------------------------------- | +| `AddLiquidity` | `EulerSwap` | Emitted when liquidity is added to the pool | Track liquidity inflows | +| `RemoveLiquidity` | `EulerSwap` | Emitted when liquidity is removed from the pool | Monitor liquidity outflows | +| `Swap` | `EulerSwap` | Emitted during token swaps | Trading analytics and UIs | +| `CollectFees` | `EulerSwap` | Emitted when trading fees are collected | Revenue and protocol fee management | +| `StatusChanged` | `EulerSwap` | Signals a change in the contract's operational status | DApp integration and state management | +| `DebtLimitUpdated` | `EulerSwap` | Emitted when debt limits for assets are modified | Risk management and protocol settings | +| `ErrorOccurred` | `EulerSwap` | Captures errors and exceptions | Debugging and transaction monitoring | +| `EulerSwapCreated` | `EulerSwapFactory` | Emitted when a new `EulerSwap` instance is created | Track creation of new liquidity pools | +| `PoolDeployed` | `EulerSwapFactory` | Indicates when a new liquidity pool is deployed | Detecting and listing new pools | + +## Details + +### Events in `EulerSwap.sol` + +#### Liquidity management events + +##### `AddLiquidity` + +```solidity +event AddLiquidity(address indexed provider, uint256 amount0, uint256 amount1); +``` + +- **Purpose:** Emitted when liquidity is added to the pool. +- **Parameters:** + - `provider`: Address adding liquidity. + - `amount0`, `amount1`: Quantities of `asset0` and `asset1` added. +- **Use Case:** Helps liquidity providers and analytics tools track liquidity inflows. + +##### `RemoveLiquidity` + +```solidity +event RemoveLiquidity(address indexed provider, uint256 amount0, uint256 amount1); +``` + +- **Purpose:** Indicates when liquidity is withdrawn from the pool. +- **Parameters:** + - `provider`: Address removing liquidity. + - `amount0`, `amount1`: Quantities of `asset0` and `asset1` withdrawn. +- **Use Case:** Updates frontends and liquidity dashboards with outflows. + +#### Trading events + +##### `Swap` + +```solidity +event Swap(address indexed trader, address indexed assetIn, address indexed assetOut, uint256 amountIn, uint256 amountOut); +``` + +- **Purpose:** Emitted during token swaps. +- **Parameters:** + - `trader`: Address executing the swap. + - `assetIn`, `assetOut`: Assets being swapped. + - `amountIn`, `amountOut`: Amounts involved in the swap. +- **Use Case:** Crucial for trade analytics, swap history, and integration with trading UIs. + +#### Fee & accounting events + +##### `CollectFees` + +```solidity +event CollectFees(address indexed collector, uint256 fees0, uint256 fees1); +``` + +- **Purpose:** Tracks when trading fees are collected. +- **Parameters:** + - `collector`: Address receiving the fees. + - `fees0`, `fees1`: Fees collected in `asset0` and `asset1`. +- **Use Case:** Important for revenue tracking and protocol fee management. + +#### Administrative & status events + +##### `StatusChanged` + +```solidity +event StatusChanged(uint32 oldStatus, uint32 newStatus); +``` + +- **Purpose:** Signals a change in the contract's operational status. +- **Parameters:** + - `oldStatus`, `newStatus`: Numerical representation of the contract status (e.g., `0 = unactivated`, `1 = unlocked`, `2 = locked`). +- **Use Case:** Enables dApps to adjust their behavior based on the contract state. + +##### `DebtLimitUpdated` + +```solidity +event DebtLimitUpdated(uint112 newDebtLimit0, uint112 newDebtLimit1); +``` + +- **Purpose:** Notifies when the debt limits for the assets are updated. +- **Parameters:** + - `newDebtLimit0`, `newDebtLimit1`: New debt limits for `asset0` and `asset1`. +- **Use Case:** Supports risk management and off-chain monitoring of protocol settings. + +### Events in `EulerSwapFactory.sol` + +##### `EulerSwapCreated` + +```solidity +event EulerSwapCreated(address indexed asset0, address indexed asset1); +``` + +- **Purpose:** Emitted when a new `EulerSwap` instance is created. +- **Parameters:** + - `asset0`, `asset1`: Addresses of the tokens in the newly created trading pair. +- **Use Case:** Useful for tracking the creation of new liquidity pools and integrating with factory-based analytics. + +##### `PoolDeployed` + +```solidity +event PoolDeployed(address indexed pool, address indexed asset0, address indexed asset1); +``` + +- **Purpose:** Indicates when a new liquidity pool is deployed by the `EulerSwapFactory`. +- **Parameters:** + - `pool`: Address of the newly deployed pool. + - `asset0`, `asset1`: Addresses of the tokens in the pool. +- **Use Case:** Essential for detecting new pool deployments, often used by front-end interfaces to list available pools dynamically. + +### Error handling events + +##### `ErrorOccurred` + +```solidity +event ErrorOccurred(address indexed account, string message); +``` + +- **Purpose:** Emitted when an error or unexpected condition occurs. +- **Parameters:** + - `account`: Address involved in the error. + - `message`: Description of the error. +- **Use Case:** Useful for debugging and alerting systems about failed transactions or invalid operations. From c1e1c257a287425a1b692cd188f5611f23822b7a Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Tue, 4 Mar 2025 09:45:09 +0000 Subject: [PATCH 179/312] feat: add errors.md file --- docs/errors.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 docs/errors.md diff --git a/docs/errors.md b/docs/errors.md new file mode 100644 index 0000000..4de54ec --- /dev/null +++ b/docs/errors.md @@ -0,0 +1,47 @@ +# Errors + +## Introduction + +The EulerSwap smart contracts throw errors that can help developers debug why EulerSwap instances are failing to provide quotes, satisfy swaps, rebalance, and more. In some cases these errors emerge directly from the EulerSwap smart contracts themselves, while errors can also come from lower level dependencies, such as the Euler Vault Kit (EVK) and Ethereum Vault Connector (EVC). Each error is listed here with its name and a description of when and why it might occur. + +## Summary + +### E_AccountLiquidity + +**Description:** This error is thrown when the liquidity provider account on Euler does not have sufficient liquidity to perform a particular action, such as borrowing or swapping assets. It typically indicates that the collateral value is not enough to cover the desired transaction within the EVK module. + +### E_AmountTooLargeToEncode + +**Description:** TODO. + +### E_BadAddress + +**Description:** This error is triggered when an invalid or null address is provided as an input. It is commonly associated with interactions where a recipient, sender, or contract address must be validated before proceeding with a transaction. + +### E_BadAssetReceiver + +**Description:** Thrown when an asset is directed to an unintended or incompatible receiver contract. This error often prevents token transfers to addresses that do not implement necessary interfaces or are not approved within the EVK and EVC architecture. + +### E_BadBorrowCap + +**Description:** This error indicates that the specified borrowing cap for an asset is invalid, either being too high or too low according to protocol parameters. It helps maintain stability by enforcing borrowing limits in the EVK. + +### E_BadCollateral + +**Description:** Raised when an invalid asset is proposed as collateral in a transaction. The EVK system uses this error to ensure only approved and properly configured assets are used to back borrowing positions. + +### E_BadFee + +**Description:** This error is related to fee calculations within the EulerSwap or associated periphery contracts. It ensures that any fee applied during swaps or vault interactions is within the acceptable bounds set by governance or protocol parameters. + +### E_BadMaxLiquidationDiscount + +**Description:** Thrown when an invalid maximum liquidation discount is set. Liquidation discounts are critical for maintaining incentives for liquidators while protecting the protocol from excessive losses during liquidation events. + +### E_BadSharesOwner + +**Description:** This error indicates that the shares of a vault or liquidity pool are owned by an unexpected or unauthorised entity. It ensures that share ownership is consistent with the expected state of the EVK or EVC modules. + +## Further reading + +For more information, refer to the EulerSwap [White Paper](docs/whitepaper/EulerSwap_White_Paper.pdf) and the smart contract source code. From 398ba38c7f2580925fbeb6af6e243a1451fb29cd Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 3 Mar 2025 14:13:38 -0500 Subject: [PATCH 180/312] Check for reserves overflow in verify() function - Gas is not a concern anymore if we are moving from binary search - Removes need for separate overflow checks in constructor --- src/EulerSwap.sol | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 19e0ea7..87cecc8 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -66,11 +66,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { // EulerSwap params require(params.fee < 1e18, BadParam()); - require( - params.equilibriumReserve0 <= type(uint112).max && params.equilibriumReserve1 <= type(uint112).max, - BadParam() - ); - require(params.currReserve0 <= type(uint112).max && params.currReserve1 <= type(uint112).max, BadParam()); require(curveParams.priceX > 0 && curveParams.priceY > 0, BadParam()); require(curveParams.priceX <= 1e36 && curveParams.priceY <= 1e36, BadParam()); require(curveParams.concentrationX <= 1e18 && curveParams.concentrationY <= 1e18, BadParam()); @@ -100,6 +95,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { // Validate reserves + require(verify(equilibriumReserve0, equilibriumReserve1), CurveViolation()); require(verify(reserve0, reserve1), CurveViolation()); require(!verify(reserve0 > 0 ? reserve0 - 1 : 0, reserve1 > 0 ? reserve1 - 1 : 0), CurveViolation()); @@ -135,7 +131,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { uint256 newReserve0 = reserve0 + amount0In - amount0Out; uint256 newReserve1 = reserve1 + amount1In - amount1Out; - require(newReserve0 <= type(uint112).max && newReserve1 <= type(uint112).max, Overflow()); require(verify(newReserve0, newReserve1), CurveViolation()); reserve0 = uint112(newReserve0); @@ -191,6 +186,8 @@ contract EulerSwap is IEulerSwap, EVCUtil { /// @inheritdoc IEulerSwap function verify(uint256 newReserve0, uint256 newReserve1) public view returns (bool) { + if (newReserve0 > type(uint112).max || newReserve1 > type(uint112).max) return false; + if (newReserve0 >= equilibriumReserve0) { if (newReserve1 >= equilibriumReserve1) return true; return From 02db36d8da7257e797b2dacf73efd7a75386d5ba Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 4 Mar 2025 16:53:06 -0500 Subject: [PATCH 181/312] periphery: getLimits --- src/EulerSwapPeriphery.sol | 77 +++++++++++++++++++++++++++++++++----- test/Limits.t.sol | 63 +++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 test/Limits.t.sol diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index f6da632..8b75664 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -102,15 +102,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { // exactIn: decrease received amountIn, rounding down if (exactIn) amount = amount * feeMultiplier / 1e18; - bool asset0IsInput; - { - address asset0 = eulerSwap.asset0(); - address asset1 = eulerSwap.asset1(); - - if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true; - else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; - else revert UnsupportedPair(); - } + bool asset0IsInput = checkTokens(eulerSwap, tokenIn, tokenOut); uint256 quote = binarySearch(eulerSwap, reserve0, reserve1, amount, exactIn, asset0IsInput); @@ -242,4 +234,71 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { // Compute and return x = fInverse(y) using the quadratic formula return Math.mulDiv(uint256(int256(sqrt) - B), 1e18, A, Math.Rounding.Ceil); } + + /// @dev Max amount the pool can buy of tokenIn and sell of tokenOut + function getLimits(address eulerSwap, address tokenIn, address tokenOut) + external + view + returns (uint256 inLimit, uint256 outLimit) + { + IEulerSwap es = IEulerSwap(eulerSwap); + if (!IEVC(es.EVC()).isAccountOperatorAuthorized(es.eulerAccount(), eulerSwap)) return (0, 0); + + inLimit = outLimit = type(uint112).max; + bool asset0IsInput = checkTokens(es, tokenIn, tokenOut); + + // Supply caps on input + { + IEVault vault = IEVault(asset0IsInput ? es.vault0() : es.vault1()); + uint256 maxDeposit = vault.debtOf(es.eulerAccount()) + vault.maxDeposit(es.eulerAccount()); + if (maxDeposit < inLimit) inLimit = maxDeposit; + } + + // Remaining reserves of output + + { + (uint112 reserve0, uint112 reserve1,) = es.getReserves(); + uint112 reserveLimit = asset0IsInput ? reserve1 : reserve0; + if (reserveLimit < outLimit) outLimit = reserveLimit; + } + + // Remaining cash and borrow caps in output + + { + IEVault vault = IEVault(asset0IsInput ? es.vault1() : es.vault0()); + + uint256 cash = vault.cash(); + if (cash < outLimit) outLimit = cash; + + (, uint16 borrowCap) = vault.caps(); + uint256 maxWithdraw = decodeCap(uint256(borrowCap)); + maxWithdraw = vault.totalBorrows() > maxWithdraw ? 0 : maxWithdraw - vault.totalBorrows(); + if (maxWithdraw > cash) maxWithdraw = cash; + maxWithdraw += vault.convertToAssets(vault.balanceOf(es.eulerAccount())); + if (maxWithdraw < outLimit) outLimit = maxWithdraw; + } + } + + function decodeCap(uint256 amountCap) internal pure returns (uint256) { + if (amountCap == 0) return type(uint256).max; + + unchecked { + // Cannot overflow because this is less than 2**256: + // 10**(2**6 - 1) * (2**10 - 1) = 1.023e+66 + return 10 ** (amountCap & 63) * (amountCap >> 6) / 100; + } + } + + function checkTokens(IEulerSwap eulerSwap, address tokenIn, address tokenOut) + internal + view + returns (bool asset0IsInput) + { + address asset0 = eulerSwap.asset0(); + address asset1 = eulerSwap.asset1(); + + if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true; + else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; + else revert UnsupportedPair(); + } } diff --git a/test/Limits.t.sol b/test/Limits.t.sol new file mode 100644 index 0000000..9256dfd --- /dev/null +++ b/test/Limits.t.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; + +import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol"; + +contract LimitsTest is EulerSwapTestBase { + EulerSwap public eulerSwap; + + function setUp() public virtual override { + super.setUp(); + + eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + } + + function test_basicLimits() public { + (uint256 inLimit, uint256 outLimit) = + periphery.getLimits(address(eulerSwap), address(assetTST), address(assetTST2)); + + assertEq(inLimit, type(uint112).max - 110e18); // max uint minus 110 (100 deposited by depositor, 10 by holder) + assertEq(outLimit, 60e18); + } + + function test_supplyCapExceeded() public { + eTST.setCaps(uint16(2.72e2 << 6) | 18, 0); + + (uint256 inLimit, uint256 outLimit) = + periphery.getLimits(address(eulerSwap), address(assetTST), address(assetTST2)); + + assertEq(inLimit, 0); // cap exceeded + assertEq(outLimit, 60e18); + } + + function test_supplyCapExtra() public { + eTST.setCaps(uint16(2.72e2 << 6) | (18 + 2), 0); + + (uint256 inLimit, uint256 outLimit) = + periphery.getLimits(address(eulerSwap), address(assetTST), address(assetTST2)); + + assertEq(inLimit, 162e18); // 272 - 110 + assertEq(outLimit, 60e18); + } + + function test_utilisation() public { + vm.prank(depositor); + eTST2.withdraw(95e18, address(depositor), address(depositor)); + + (uint256 inLimit, uint256 outLimit) = + periphery.getLimits(address(eulerSwap), address(assetTST), address(assetTST2)); + + assertEq(inLimit, type(uint112).max - 110e18); + assertEq(outLimit, 15e18); // 110 - 95 + } + + function test_borrowCap() public { + eTST2.setCaps(0, uint16(8.5e2 << 6) | 18); + + (uint256 inLimit, uint256 outLimit) = + periphery.getLimits(address(eulerSwap), address(assetTST), address(assetTST2)); + + assertEq(inLimit, type(uint112).max - 110e18); + assertEq(outLimit, 18.5e18); // 10 in balance, plus 8.5 borrow cap + } +} From d6fc4adb9f1050f1348bfff5db3603f2482ba705 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Tue, 4 Mar 2025 22:59:35 +0000 Subject: [PATCH 182/312] feat: complete boundary analysis docs for f() and fInverse() --- docs/boundary-analysis.md | 138 +++++++++++++++++++++++++++++++++++++ docs/f.md | 60 ---------------- src/EulerSwapPeriphery.sol | 11 ++- 3 files changed, 142 insertions(+), 67 deletions(-) create mode 100644 docs/boundary-analysis.md delete mode 100644 docs/f.md diff --git a/docs/boundary-analysis.md b/docs/boundary-analysis.md new file mode 100644 index 0000000..45a27ed --- /dev/null +++ b/docs/boundary-analysis.md @@ -0,0 +1,138 @@ +# Boundary analysis + +## Introduction + +The EulerSwap automated market maker (AMM) curve is governed by two key functions: f() and fInverse(). These functions are critical to maintaining protocol invariants and ensuring accurate swap calculations within the AMM. This document provides a detailed boundary analysis of both functions, assessing their Solidity implementations against the equations in the white paper. It ensures that appropriate safety measures are in place to avoid overflow, underflow, and precision loss, and that unchecked operations are thoroughly justified. + +## Implementation of function `f()` + +The `f()` function is part of the EulerSwap core, defined in `EulerSwap.sol`, and corresponds to equation (2) in the EulerSwap white paper. The `f()` function is a parameterisable curve in the `EulerSwap` contract that defines the permissible boundary for points in EulerSwap AMMs. The curve allows points on or above and to the right of the curve while restricting others. Its primary purpose is to act as an invariant validator by checking if a hypothetical state `(x, y)` within the AMM is valid. It also calculates swap output amounts for given inputs, though some swap scenarios require `fInverse()`. + +### Derivation + +This derivation shows how to implement the `f()` function in Solidity, starting from the theoretical model described in the EulerSwap white paper. The initial equation from the EulerSwap white paper is: + +\[ +y_0 + \left(\frac{p_x}{p_y}\right) (x_0 - x) \left(c + (1 - c) \frac{x_0}{x}\right) +\] + +Multiply the second term by \(\frac{x}{x}\) and scale `c` by \(1e18\): + +\[ +y_0 + \left(\frac{p_x}{p_y}\right) (x_0 - x) \frac{(c \cdot x) + (1e18 - c) \cdot x_0}{x \cdot 1e18} +\] + +Reorder division by \(p_y\) to prepare for Solidity implementation: + +\[ +y_0 + p_x \cdot (x_0 - x) \cdot \frac{(c \cdot x) + (1e18 - c) \cdot x_0}{x \cdot 1e18} \cdot \frac{1}{p_y} +\] + +To avoid intermediate overflow, use `Math.mulDiv` in Solidity, which combines multiplication and division safely: + +\[ +y_0 + \frac{\text{Math.mulDiv}(p_x \cdot (x_0 - x), c \cdot x + (1e18 - c) \cdot x_0, x \cdot 1e18)}{p_y} +\] + +Applying ceiling rounding with `Math.Rounding.Ceil` ensures accuracy: + +\[ +y_0 + \left(\text{Math.mulDiv}(p_x \cdot (x_0 - x), c \cdot x + (1e18 - c) \cdot x_0, x \cdot 1e18, \text{Math.Rounding.Ceil}) + (p_y - 1)\right) / p_y +\] + +Adding `(p_y - 1)` ensures proper ceiling rounding by making sure the result is rounded up when the numerator is not perfectly divisible by `p_y`. + +### Boundary analysis + +#### Pre-conditions + +- \(x \leq x_0\) +- \(1e18 \leq p_x, p_y \leq 1e36\) (60 to 120 bits) +- \(1 \leq x_0, y_0 \leq 2^{112} - 1 \approx 5.19e33\) (0 to 112 bits) +- \(1 < c \leq 1e18\) (0 to 60 bits) + +#### Step-by-step + +The arguments to `mulDiv` are safe from overflow: + +- **Arg 1:** `px * (x0 - x)` ≤ `1e36 * (2**112 - 1)` ≈ 232 bits +- **Arg 2:** `c * x + (1e18 - c) * x0` ≤ `1e18 * (2**112 - 1) * 2` ≈ 173 bits +- **Arg 3:** `x * 1e18` ≤ `1e18 * (2**112 - 1)` ≈ 172 bits + +If `mulDiv` or the addition with `y0` overflows, the result would exceed `type(uint112).max`. When `mulDiv` overflows, its result would be > `2**256 - 1`. Dividing by `py` (`1e36` max) gives ~`2**136`, which exceeds the `2**112 - 1` limit, meaning these results are invalid as they cannot be satisfied by any swapper. + +#### Unchecked math considerations + +The arguments to `mulDiv` are protected from overflow as demonstrated above. The `mulDiv` output is further limited to `2**248 - 1` to prevent overflow in subsequent operations: + +```solidity +unchecked { + uint256 v = Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil); + require(v <= type(uint248).max, Overflow()); + return y0 + (v + (py - 1)) / py; +} +``` + +This does not introduce additional failure cases. Even values between `2**248 - 1` and `2**256 - 1` would not reduce to `2**112 - 1`, aligning with the boundary analysis. + +## Implementation of function `fInverse()` + +The `fInverse()` function, defined in `EulerSwapPeriphery.sol`, is part of the periphery because it is not required as an invariant. Instead, its sole purpose is to facilitate specific swap input and output calculations that cannot be managed by `f()`. This function maps to equation (22) in the Appendix of the EulerSwap white paper. + +### Boundary analysis + +#### Pre-conditions + +- \(y > y_0\) +- \(1e18 \leq p_x, p_y \leq 1e36\) (60 to 120 bits) +- \(1 \leq x_0, y_0 \leq 2^{112} - 1 \approx 5.19e33\) (0 to 112 bits) +- \(1 < c \leq 1e18\) (0 to 60 bits) + +#### Step-by-step + +1. **A component (`A = 2 * c`)** + + - Since `c <= 1e18`, `A = 2 * c <= 2e18`, well within `uint256` capacity (max `2**256 - 1`). + +2. **B component calculation** + + - `B = int256((px * (y - y0) + py - 1) / py) - int256((x0 * (2 * c - 1e18) + 1e18 - 1) / 1e18)` + - The first term is bounded by `(px * (y - y0)) / py`, where `px, py <= 1e36` and `(y - y0) <= 2**112 - 1`. + - The second term scales `x0` with `(2 * c - 1e18)`, keeping the result well within the `int256` bounds due to controlled arithmetic and the limits on `c` and `x0`. + +3. **Absolute value and B² computation** + + - `absB = B < 0 ? uint256(-B) : uint256(B)` + - `squaredB = Math.mulDiv(absB, absB, 1e18, Math.Rounding.Ceil)` + - As `absB` is derived from `B`, and `B` is bounded, `squaredB` remains within a safe range. + +4. **4AC Component (`AC4 = AC4a * AC4b / 1e18`)** + + - `AC4a = Math.mulDiv(4 * c, (1e18 - c), 1e18, Math.Rounding.Ceil)` + - `4 * c * (1e18 - c)` has a maximum of `1e18 * 1e18 = 1e36`, divided by `1e18`, the result ≤ `1e18`. + - `AC4b = Math.mulDiv(x0, x0, 1e18, Math.Rounding.Ceil)` + - The maximum value of `x0 * x0` is `(2**112 - 1)² ≈ 2**224`, safely within the `uint256` range. + +5. **Discriminant calculation** + + - `discriminant = (squaredB + AC4) * 1e18` + - Since both `squaredB` and `AC4` are bounded by `uint256`, multiplying by `1e18` does not cause overflow. + +6. **Square root computation and adjustment** + + - `uint256 sqrt = Math.sqrt(discriminant)` + - The square root of a `uint256` value is always within `uint128`, making this operation safe. + - Adjustment step `sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt` maintains precision without overflow. + +7. **Final computation of `x`** + - `Math.mulDiv(uint256(int256(sqrt) - B), 1e18, A, Math.Rounding.Ceil)` + - The subtraction and multiplication are controlled by previous bounds, ensuring no overflow. + - Division by `A` is safe as `A` is non-zero and small (`≤ 2e18`). + +#### Unchecked math considerations + +As above, the use of unchecked arithmetic is safe because all inputs are bounded by pre-conditions. + +## Conclusion + +The `f()` and `fInverse()` functions of EulerSwap are implemented with rigorous safety measures, using `Math.mulDiv` for safe arithmetic and applying ceiling rounding to maintain precision. Boundary analysis shows that all potential overflow scenarios are precluded by pre-condition checks and bounded operations, justifying the use of unchecked math in the Solidity implementation. diff --git a/docs/f.md b/docs/f.md deleted file mode 100644 index 2ccc23e..0000000 --- a/docs/f.md +++ /dev/null @@ -1,60 +0,0 @@ -## Implementation of `f` - -`f` (aka the "EulerSwap Function") is a parameterisable curve that defines the boundary of permissible points for EulerSwap AMMs. Points on the curve or above and to-the right are allowed, others are not. - -Only formula 3 from the whitepaper is implemented in the EulerSwap core, since this can be used for both domains of the curve by mirroring the parameters. The more complicated formula 4 is a closed-form method for quoting swaps so it can be implemented in a periphery (if desired). - -### Derivation - -Formula 3 from the whitepaper: - - y0 + (px / py) * (x0 - x) * (c + (1 - c) * (x0 / x)) - -Multiply second term by `x/x`: - - y0 + (px / py) * (x0 - x) * ((c * x) + (1 - c) * x0) / x - -`c` is scaled by `1e18`: - - y0 + (px / py) * (x0 - x) * ((c * x) + (1e18 - c) * x0) / (x * 1e18) - -Re-order division by `py`: - - y0 + px * (x0 - x) * ((c * x) + (1e18 - c) * x0) / (x * 1e18) / py - -Use `mulDiv` to avoid intermediate overflow: - - y0 + Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18) / py - -Round up for both divisions (operation is distributive): - - y0 + (Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil) + (py-1)) / py - -### Boundary Analysis - -Pre-conditions: x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 - -None of the computations for the arguments to `mulDiv` can overflow: - -* Arg 1: `px * (x0 - x)` - * Upper-bound: `1e36*(2**112 - 1) =~ 232 bits` -* Arg 2: `c * x + (1e18 - c) * x0` - * Upper-bound: `1e18*(2**112 - 1)*2 =~ 173 bits` -* Arg 3: `x * 1e18` - * Upper-bound: `1e18*(2**112 - 1) =~ 172 bits` - -If amounts/prices are large, and we travel too far down the curve, then `mulDiv` (or the subsequent `y0` addition) could overflow because its output value cannot be represented as a `uint256`. However, these output values would never be valid anyway, because they exceed `type(uint112).max`. - -To see this, consider the case where `mulDiv` fails due to overflow. This means that its result would've been greater than `2**256 - 1`. Dividing this value by the largest allowed value for `py` (`1e36`) gives approximately `2**136`, which is greater than the maximum allowed amount value of `2**112 - 1`. Both the rounding up operation and the final addition of `y0` can only further *increase* this value. This means that all cases where `mulDiv` or the subsequent additions overflow would involve `f()` returning values that are impossible for a swapper to satisfy, so they would revert anyways. - -### Unchecked Math - -As-per the previous section, none of the computations of the arguments to `mulDiv` can overflow. To prevent overflows in the remaining operations, the `mulDiv` output is further restricted to `2**248 - 1`: - - unchecked { - uint256 v = Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil); - require(v <= type(uint248).max, Overflow()); - return y0 + (v + (py - 1)) / py; - } - -Note that this does not change the analysis of the previous section: Values between `2**248 - 1` and `2**256 - 1` will also never reduce down to the required `2**112 - 1`, so this does not cause any additional failure cases. diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index f6da632..5784651 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -214,7 +214,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { pure returns (uint256) { - // A component of the quadratic formula: a = 2 * c + // A component of the quadratic formula uint256 A = 2 * c; // B component of the quadratic formula @@ -225,12 +225,9 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { uint256 squaredB = Math.mulDiv(absB, absB, 1e18, Math.Rounding.Ceil); // 4 * A * C component of the quadratic formula - uint256 AC4 = Math.mulDiv( - Math.mulDiv(4 * c, (1e18 - c), 1e18, Math.Rounding.Ceil), - Math.mulDiv(x0, x0, 1e18, Math.Rounding.Ceil), - 1e18, - Math.Rounding.Ceil - ); + uint256 AC4a = Math.mulDiv(4 * c, (1e18 - c), 1e18, Math.Rounding.Ceil); + uint256 AC4b = Math.mulDiv(x0, x0, 1e18, Math.Rounding.Ceil); + uint256 AC4 = Math.mulDiv(AC4a, AC4b, 1e18, Math.Rounding.Ceil); // Discriminant: b^2 + 4ac, scaled up to maintain precision uint256 discriminant = (squaredB + AC4) * 1e18; From 1400cc0c95a09077912e70ea06fe5076ccc1b42e Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Tue, 4 Mar 2025 23:09:57 +0000 Subject: [PATCH 183/312] feat: add unchecked to fInverse() --- src/EulerSwapPeriphery.sol | 50 ++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index f6da632..f1a5fb7 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -214,32 +214,34 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { pure returns (uint256) { - // A component of the quadratic formula: a = 2 * c - uint256 A = 2 * c; - - // B component of the quadratic formula - int256 B = int256((px * (y - y0) + py - 1) / py) - int256((x0 * (2 * c - 1e18) + 1e18 - 1) / 1e18); - - // B^2 component, using FullMath for overflow safety - uint256 absB = B < 0 ? uint256(-B) : uint256(B); - uint256 squaredB = Math.mulDiv(absB, absB, 1e18, Math.Rounding.Ceil); - - // 4 * A * C component of the quadratic formula - uint256 AC4 = Math.mulDiv( - Math.mulDiv(4 * c, (1e18 - c), 1e18, Math.Rounding.Ceil), - Math.mulDiv(x0, x0, 1e18, Math.Rounding.Ceil), - 1e18, - Math.Rounding.Ceil - ); + unchecked { + // A component of the quadratic formula: a = 2 * c + uint256 A = 2 * c; + + // B component of the quadratic formula + int256 B = int256((px * (y - y0) + py - 1) / py) - int256((x0 * (2 * c - 1e18) + 1e18 - 1) / 1e18); - // Discriminant: b^2 + 4ac, scaled up to maintain precision - uint256 discriminant = (squaredB + AC4) * 1e18; + // B^2 component, using FullMath for overflow safety + uint256 absB = B < 0 ? uint256(-B) : uint256(B); + uint256 squaredB = Math.mulDiv(absB, absB, 1e18, Math.Rounding.Ceil); - // Square root of the discriminant (rounded up) - uint256 sqrt = Math.sqrt(discriminant); - sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; + // 4 * A * C component of the quadratic formula + uint256 AC4 = Math.mulDiv( + Math.mulDiv(4 * c, (1e18 - c), 1e18, Math.Rounding.Ceil), + Math.mulDiv(x0, x0, 1e18, Math.Rounding.Ceil), + 1e18, + Math.Rounding.Ceil + ); - // Compute and return x = fInverse(y) using the quadratic formula - return Math.mulDiv(uint256(int256(sqrt) - B), 1e18, A, Math.Rounding.Ceil); + // Discriminant: b^2 + 4ac, scaled up to maintain precision + uint256 discriminant = (squaredB + AC4) * 1e18; + + // Square root of the discriminant (rounded up) + uint256 sqrt = Math.sqrt(discriminant); + sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; + + // Compute and return x = fInverse(y) using the quadratic formula + return Math.mulDiv(uint256(int256(sqrt) - B), 1e18, A, Math.Rounding.Ceil); + } } } From c64b5b57ca28c9e461a3f4c3f731ef3e7a4014f9 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 4 Mar 2025 23:15:03 -0500 Subject: [PATCH 184/312] refactor quoting to share logic with getLimits --- src/EulerSwapPeriphery.sol | 29 +++++++++++----------- test/Limits.t.sol | 49 +++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 15 deletions(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index 8b75664..ebce34d 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -12,8 +12,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { error UnsupportedPair(); error OperatorNotInstalled(); - error InsufficientReserves(); - error InsufficientCash(); + error SwapLimitExceeded(); error AmountOutLessThanMin(); error AmountInMoreThanMax(); @@ -93,27 +92,25 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { IEVC(eulerSwap.EVC()).isAccountOperatorAuthorized(eulerSwap.eulerAccount(), address(eulerSwap)), OperatorNotInstalled() ); + require(amount <= type(uint112).max, SwapLimitExceeded()); uint256 feeMultiplier = eulerSwap.feeMultiplier(); - address vault0 = eulerSwap.vault0(); - address vault1 = eulerSwap.vault1(); (uint112 reserve0, uint112 reserve1,) = eulerSwap.getReserves(); // exactIn: decrease received amountIn, rounding down if (exactIn) amount = amount * feeMultiplier / 1e18; bool asset0IsInput = checkTokens(eulerSwap, tokenIn, tokenOut); + (uint256 inLimit, uint256 outLimit) = _getLimits(eulerSwap, asset0IsInput); uint256 quote = binarySearch(eulerSwap, reserve0, reserve1, amount, exactIn, asset0IsInput); if (exactIn) { // if `exactIn`, `quote` is the amount of assets to buy from the AMM - require(quote <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); - require(quote <= IEVault(asset0IsInput ? vault1 : vault0).cash(), InsufficientCash()); + require(amount <= inLimit && quote <= outLimit, SwapLimitExceeded()); } else { // if `!exactIn`, `amount` is the amount of assets to buy from the AMM - require(amount <= (asset0IsInput ? reserve1 : reserve0), InsufficientReserves()); - require(amount <= IEVault(asset0IsInput ? vault1 : vault0).cash(), InsufficientCash()); + require(amount <= outLimit && quote <= inLimit, SwapLimitExceeded()); } // exactOut: increase required quote(amountIn), rounding up @@ -161,8 +158,9 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { while (low < high) { uint256 mid = (low + high) / 2; - if (dy == 0 ? eulerSwap.verify(uint256(reserve0New), mid) : eulerSwap.verify(mid, uint256(reserve1New))) - { + (uint256 a, uint256 b) = dy == 0 ? (uint256(reserve0New), mid) : (mid, uint256(reserve1New)); + require(a > 0 && b > 0, SwapLimitExceeded()); + if (eulerSwap.verify(a, b)) { high = mid; } else { low = mid + 1; @@ -235,19 +233,22 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { return Math.mulDiv(uint256(int256(sqrt) - B), 1e18, A, Math.Rounding.Ceil); } - /// @dev Max amount the pool can buy of tokenIn and sell of tokenOut + /// @notice Max amount the pool can buy of tokenIn and sell of tokenOut function getLimits(address eulerSwap, address tokenIn, address tokenOut) external view returns (uint256 inLimit, uint256 outLimit) { - IEulerSwap es = IEulerSwap(eulerSwap); - if (!IEVC(es.EVC()).isAccountOperatorAuthorized(es.eulerAccount(), eulerSwap)) return (0, 0); + return _getLimits(IEulerSwap(eulerSwap), checkTokens(IEulerSwap(eulerSwap), tokenIn, tokenOut)); + } + + function _getLimits(IEulerSwap es, bool asset0IsInput) internal view returns (uint256 inLimit, uint256 outLimit) { + if (!IEVC(es.EVC()).isAccountOperatorAuthorized(es.eulerAccount(), address(es))) return (0, 0); inLimit = outLimit = type(uint112).max; - bool asset0IsInput = checkTokens(es, tokenIn, tokenOut); // Supply caps on input + { IEVault vault = IEVault(asset0IsInput ? es.vault0() : es.vault1()); uint256 maxDeposit = vault.debtOf(es.eulerAccount()) + vault.maxDeposit(es.eulerAccount()); diff --git a/test/Limits.t.sol b/test/Limits.t.sol index 9256dfd..6bf57bd 100644 --- a/test/Limits.t.sol +++ b/test/Limits.t.sol @@ -9,7 +9,7 @@ contract LimitsTest is EulerSwapTestBase { function setUp() public virtual override { super.setUp(); - eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.9e18, 0.9e18); } function test_basicLimits() public { @@ -18,6 +18,33 @@ contract LimitsTest is EulerSwapTestBase { assertEq(inLimit, type(uint112).max - 110e18); // max uint minus 110 (100 deposited by depositor, 10 by holder) assertEq(outLimit, 60e18); + + // Exact output + + uint256 quote = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), 50e18); + assertEq(quote, 75e18); + + quote = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), 59.9999999e18); + assertApproxEqAbs(quote, 3.6e27, 0.1e27); + + vm.expectRevert(EulerSwapPeriphery.SwapLimitExceeded.selector); + quote = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), 60e18); + + vm.expectRevert(EulerSwapPeriphery.SwapLimitExceeded.selector); + quote = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), 60.000001e18); + + // Exact input + + vm.expectRevert(EulerSwapPeriphery.SwapLimitExceeded.selector); + quote = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), type(uint112).max); + } + + function test_basicLimitsReverse() public view { + (uint256 inLimit, uint256 outLimit) = + periphery.getLimits(address(eulerSwap), address(assetTST2), address(assetTST)); + + assertEq(outLimit, 60e18); + assertEq(inLimit, type(uint112).max - 110e18); } function test_supplyCapExceeded() public { @@ -28,6 +55,19 @@ contract LimitsTest is EulerSwapTestBase { assertEq(inLimit, 0); // cap exceeded assertEq(outLimit, 60e18); + + vm.expectRevert(EulerSwapPeriphery.SwapLimitExceeded.selector); + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), 1); + } + + function test_supplyCapExceededReverse() public { + eTST2.setCaps(uint16(2.72e2 << 6) | 18, 0); + + (uint256 inLimit, uint256 outLimit) = + periphery.getLimits(address(eulerSwap), address(assetTST2), address(assetTST)); + + assertEq(inLimit, 0); // cap exceeded + assertEq(outLimit, 60e18); } function test_supplyCapExtra() public { @@ -38,6 +78,13 @@ contract LimitsTest is EulerSwapTestBase { assertEq(inLimit, 162e18); // 272 - 110 assertEq(outLimit, 60e18); + + uint256 quote = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), 161.9999e18); + assertApproxEqAbs(quote, 56.9e18, 0.1e18); + + vm.expectRevert(EulerSwapPeriphery.SwapLimitExceeded.selector); + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), 162e18 + 1); } function test_utilisation() public { From 14616041aa50e9c7f079faa324c783d06ee2150e Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 5 Mar 2025 00:41:14 -0500 Subject: [PATCH 185/312] explicitly check for swap amounts being too large (instead of depending on checked arithmetic overflows) --- src/EulerSwap.sol | 3 +++ test/Limits.t.sol | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index a9e3695..96580d3 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -51,6 +51,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { error Locked(); error Overflow(); error BadParam(); + error AmountTooBig(); error DifferentEVC(); error AssetsOutOfOrderOrEqual(); error CurveViolation(); @@ -105,6 +106,8 @@ contract EulerSwap is IEulerSwap, EVCUtil { callThroughEVC nonReentrant { + require(amount0Out <= type(uint112).max && amount1Out <= type(uint112).max, AmountTooBig()); + // Optimistically send tokens if (amount0Out > 0) withdrawAssets(vault0, amount0Out, to); diff --git a/test/Limits.t.sol b/test/Limits.t.sol index 6bf57bd..1e4223c 100644 --- a/test/Limits.t.sol +++ b/test/Limits.t.sol @@ -107,4 +107,12 @@ contract LimitsTest is EulerSwapTestBase { assertEq(inLimit, type(uint112).max - 110e18); assertEq(outLimit, 18.5e18); // 10 in balance, plus 8.5 borrow cap } + + function test_amountTooBig() public monotonicHolderNAV { + vm.expectRevert(EulerSwap.AmountTooBig.selector); + eulerSwap.swap(type(uint256).max, 0, address(this), ""); + + vm.expectRevert(EulerSwap.AmountTooBig.selector); + eulerSwap.swap(0, type(uint256).max, address(this), ""); + } } From bbfa0371987e84b4eca70e9e7324efd33b435c9d Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 5 Mar 2025 01:03:34 -0500 Subject: [PATCH 186/312] todo --- TODO | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/TODO b/TODO index 88cb24a..6f49436 100644 --- a/TODO +++ b/TODO @@ -1,24 +1,18 @@ -! Don't make quotes that would cause a swap to fail if supply/borrow caps exceeded -* Better revert messages when a swap fails due to maglev debt-limit/vault utilisation/etc - * currently it's an arithmetic underflow +* Better revert messages when a swap fails due to debt-limit/vault utilisation/etc + * currently they are errors thrown by the vaults or arithmetic underflows TESTING * when exchange rate in vaults != 1 -* uniswap callback, flash swaps -* hitting reserve/utilisation limits -* AssetsOutOfOrderOrEqual MISC ? A really small swap could fail because deposit() results in 0 shares, which causes EVK to revert. Call convertToShares() first? Seems like overkill... -? permit2 instead of regular approval: measure gas savings * Improve the efficiency of on-chain quoting * Probably necessary for supporting non-zero slippage swaps - * Use unchecked math in verify() (needs careful boundary analysis) - * Closed-form quoting solutions + * Use fInverse() Closed-form quoting solutions * "Range hints" for the binary search @@ -34,7 +28,3 @@ IDEAS * Could current reserves be calculated dynamically based on balances/debts/debt limits? * I guess you would lose a chunk of interest to arbitrage * Donation attacks? -* What can we do to make this easily integrated with aggregators/MEV bots/etc? - * How to handle a discovery/tracking of the different Maglev instances? - ? Factory? Registry? Maybe a fake factory that reads the actually installed operators from a set of addresses? - ? Transparent proxy so a Maglev address can stay constant \ No newline at end of file From a789a30aa43fa23bba31d915cefd11689cb7eef6 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 5 Mar 2025 15:04:07 +0900 Subject: [PATCH 187/312] forge doc --- README.md | 6 + foundry-docs/.gitignore | 1 + foundry-docs/book.css | 13 + foundry-docs/book.toml | 12 + foundry-docs/solidity.min.js | 74 ++++ foundry-docs/src/README.md | 71 ++++ foundry-docs/src/SUMMARY.md | 11 + .../src/EulerSwap.sol/contract.EulerSwap.md | 318 ++++++++++++++++++ .../contract.EulerSwapFactory.md | 168 +++++++++ .../contract.EulerSwapPeriphery.md | 219 ++++++++++++ foundry-docs/src/src/README.md | 7 + .../IEulerSwap.sol/interface.IEulerSwap.md | 177 ++++++++++ .../interface.IEulerSwapFactory.md | 35 ++ .../interface.IEulerSwapPeriphery.md | 49 +++ .../interface.IUniswapV2Callee.md | 12 + foundry-docs/src/src/interfaces/README.md | 7 + foundry.toml | 4 + 17 files changed, 1184 insertions(+) create mode 100644 foundry-docs/.gitignore create mode 100644 foundry-docs/book.css create mode 100644 foundry-docs/book.toml create mode 100644 foundry-docs/solidity.min.js create mode 100644 foundry-docs/src/README.md create mode 100644 foundry-docs/src/SUMMARY.md create mode 100644 foundry-docs/src/src/EulerSwap.sol/contract.EulerSwap.md create mode 100644 foundry-docs/src/src/EulerSwapFactory.sol/contract.EulerSwapFactory.md create mode 100644 foundry-docs/src/src/EulerSwapPeriphery.sol/contract.EulerSwapPeriphery.md create mode 100644 foundry-docs/src/src/README.md create mode 100644 foundry-docs/src/src/interfaces/IEulerSwap.sol/interface.IEulerSwap.md create mode 100644 foundry-docs/src/src/interfaces/IEulerSwapFactory.sol/interface.IEulerSwapFactory.md create mode 100644 foundry-docs/src/src/interfaces/IEulerSwapPeriphery.sol/interface.IEulerSwapPeriphery.md create mode 100644 foundry-docs/src/src/interfaces/IUniswapV2Callee.sol/interface.IUniswapV2Callee.md create mode 100644 foundry-docs/src/src/interfaces/README.md diff --git a/README.md b/README.md index 6f5ef24..3ca10ee 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,12 @@ forge test forge coverage ``` +## Smart Contracts Documentation + +```sh +forge doc --serve --port 4000 +``` + ## Safety This software is experimental and is provided "as is" and "as available". diff --git a/foundry-docs/.gitignore b/foundry-docs/.gitignore new file mode 100644 index 0000000..4e42a1b --- /dev/null +++ b/foundry-docs/.gitignore @@ -0,0 +1 @@ +book/ \ No newline at end of file diff --git a/foundry-docs/book.css b/foundry-docs/book.css new file mode 100644 index 0000000..b5ce903 --- /dev/null +++ b/foundry-docs/book.css @@ -0,0 +1,13 @@ +table { + margin: 0 auto; + border-collapse: collapse; + width: 100%; +} + +table td:first-child { + width: 15%; +} + +table td:nth-child(2) { + width: 25%; +} \ No newline at end of file diff --git a/foundry-docs/book.toml b/foundry-docs/book.toml new file mode 100644 index 0000000..62a23bf --- /dev/null +++ b/foundry-docs/book.toml @@ -0,0 +1,12 @@ +[book] +src = "src" +title = "Euler Swap Contracts Documentation" + +[output.html] +no-section-label = true +additional-js = ["solidity.min.js"] +additional-css = ["book.css"] +git-repository-url = "https://github.com/euler-xyz/euler-maglev" + +[output.html.fold] +enable = true diff --git a/foundry-docs/solidity.min.js b/foundry-docs/solidity.min.js new file mode 100644 index 0000000..1924932 --- /dev/null +++ b/foundry-docs/solidity.min.js @@ -0,0 +1,74 @@ +hljs.registerLanguage("solidity",(()=>{"use strict";function e(){try{return!0 +}catch(e){return!1}} +var a=/-?(\b0[xX]([a-fA-F0-9]_?)*[a-fA-F0-9]|(\b[1-9](_?\d)*(\.((\d_?)*\d)?)?|\.\d(_?\d)*)([eE][-+]?\d(_?\d)*)?|\b0)(?!\w|\$)/ +;e()&&(a=a.source.replace(/\\b/g,"(?{ +var a=r(e),o=l(e),c=/[A-Za-z_$][A-Za-z_$0-9.]*/,d=e.inherit(e.TITLE_MODE,{ +begin:/[A-Za-z$_][0-9A-Za-z$_]*/,lexemes:c,keywords:n}),u={className:"params", +begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,lexemes:c,keywords:n, +contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,o,s]},_={ +className:"operator",begin:/:=|->/};return{keywords:n,lexemes:c, +contains:[a,o,i,t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s,_,{ +className:"function",lexemes:c,beginKeywords:"function",end:"{",excludeEnd:!0, +contains:[d,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,_]}]}}, +solAposStringMode:r,solQuoteStringMode:l,HEX_APOS_STRING_MODE:i, +HEX_QUOTE_STRING_MODE:t,SOL_NUMBER:s,isNegativeLookbehindAvailable:e} +;const{baseAssembly:c,solAposStringMode:d,solQuoteStringMode:u,HEX_APOS_STRING_MODE:_,HEX_QUOTE_STRING_MODE:m,SOL_NUMBER:b,isNegativeLookbehindAvailable:E}=o +;return e=>{for(var a=d(e),s=u(e),n=[],i=0;i<32;i++)n[i]=i+1 +;var t=n.map((e=>8*e)),r=[];for(i=0;i<=80;i++)r[i]=i +;var l=n.map((e=>"bytes"+e)).join(" ")+" ",o=t.map((e=>"uint"+e)).join(" ")+" ",g=t.map((e=>"int"+e)).join(" ")+" ",M=[].concat.apply([],t.map((e=>r.map((a=>e+"x"+a))))),p={ +keyword:"var bool string int uint "+g+o+"byte bytes "+l+"fixed ufixed "+M.map((e=>"fixed"+e)).join(" ")+" "+M.map((e=>"ufixed"+e)).join(" ")+" enum struct mapping address new delete if else for while continue break return throw emit try catch revert unchecked _ function modifier event constructor fallback receive error virtual override constant immutable anonymous indexed storage memory calldata external public internal payable pure view private returns import from as using pragma contract interface library is abstract type assembly", +literal:"true false wei gwei szabo finney ether seconds minutes hours days weeks years", +built_in:"self this super selfdestruct suicide now msg block tx abi blockhash gasleft assert require Error Panic sha3 sha256 keccak256 ripemd160 ecrecover addmod mulmod log0 log1 log2 log3 log4" +},O={className:"operator",begin:/[+\-!~*\/%<>&^|=]/ +},C=/[A-Za-z_$][A-Za-z_$0-9]*/,N={className:"params",begin:/\(/,end:/\)/, +excludeBegin:!0,excludeEnd:!0,lexemes:C,keywords:p, +contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,s,b,"self"]},f={ +begin:/\.\s*/,end:/[^A-Za-z0-9$_\.]/,excludeBegin:!0,excludeEnd:!0,keywords:{ +built_in:"gas value selector address length push pop send transfer call callcode delegatecall staticcall balance code codehash wrap unwrap name creationCode runtimeCode interfaceId min max" +},relevance:2},y=e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/, +lexemes:C,keywords:p}),w={className:"built_in", +begin:(E()?"(?`|`address`|The address of the EVC contract.| + + +### activate + +Approves the vaults to access the EulerSwap instance's tokens, and enables +vaults as collateral. Can be invoked by anybody, and is harmless if invoked again. +Calling this function is optional: EulerSwap can be activated on the first swap. + + +```solidity +function activate() public; +``` + +### verify + +Function that defines the shape of the swapping curve. Returns true iff +the specified reserve amounts would be acceptable (ie it is above and to-the-right +of the swapping curve). + + +```solidity +function verify(uint256 newReserve0, uint256 newReserve1) public view returns (bool); +``` + +### withdrawAssets + + +```solidity +function withdrawAssets(address vault, uint256 amount, address to) internal; +``` + +### depositAssets + + +```solidity +function depositAssets(address vault, uint256 amount) internal returns (uint256); +``` + +### myDebt + + +```solidity +function myDebt(address vault) internal view returns (uint256); +``` + +### myBalance + + +```solidity +function myBalance(address vault) internal view returns (uint256); +``` + +### offsetReserve + + +```solidity +function offsetReserve(uint112 reserve, address vault) internal view returns (uint112); +``` + +### f + +*EulerSwap curve definition +Pre-conditions: x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18* + + +```solidity +function f(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256); +``` + +## Events +### EulerSwapCreated + +```solidity +event EulerSwapCreated(address indexed asset0, address indexed asset1); +``` + +### Swap + +```solidity +event Swap( + address indexed sender, + uint256 amount0In, + uint256 amount1In, + uint256 amount0Out, + uint256 amount1Out, + uint112 reserve0, + uint112 reserve1, + address indexed to +); +``` + +## Errors +### Locked + +```solidity +error Locked(); +``` + +### Overflow + +```solidity +error Overflow(); +``` + +### BadParam + +```solidity +error BadParam(); +``` + +### DifferentEVC + +```solidity +error DifferentEVC(); +``` + +### AssetsOutOfOrderOrEqual + +```solidity +error AssetsOutOfOrderOrEqual(); +``` + +### CurveViolation + +```solidity +error CurveViolation(); +``` + +### DepositFailure + +```solidity +error DepositFailure(bytes reason); +``` + diff --git a/foundry-docs/src/src/EulerSwapFactory.sol/contract.EulerSwapFactory.md b/foundry-docs/src/src/EulerSwapFactory.sol/contract.EulerSwapFactory.md new file mode 100644 index 0000000..8b45d63 --- /dev/null +++ b/foundry-docs/src/src/EulerSwapFactory.sol/contract.EulerSwapFactory.md @@ -0,0 +1,168 @@ +# EulerSwapFactory +[Git Source](https://github.com/euler-xyz/euler-maglev/blob/d6fc4adb9f1050f1348bfff5db3603f2482ba705/src/EulerSwapFactory.sol) + +**Inherits:** +[IEulerSwapFactory](/src/interfaces/IEulerSwapFactory.sol/interface.IEulerSwapFactory.md), EVCUtil + +**Author:** +Euler Labs (https://www.eulerlabs.com/) + +**Note:** +security-contact: security@euler.xyz + + +## State Variables +### allPools +*An array to store all pools addresses.* + + +```solidity +address[] public allPools; +``` + + +### eulerAccountToPool +*Mapping between euler account and deployed pool that is currently set as operator* + + +```solidity +mapping(address eulerAccount => address operator) public eulerAccountToPool; +``` + + +## Functions +### constructor + + +```solidity +constructor(address evc) EVCUtil(evc); +``` + +### deployPool + +Deploy a new EulerSwap pool with the given parameters + +*The pool address is deterministically generated using CREATE2 with a salt derived from +the euler account address and provided salt parameter. This allows the pool address to be +predicted before deployment.* + + +```solidity +function deployPool(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams, bytes32 salt) + external + returns (address); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`params`|`IEulerSwap.Params`|Core pool parameters including vaults, account, and fee settings| +|`curveParams`|`IEulerSwap.CurveParams`|Parameters defining the curve shape including prices and concentrations| +|`salt`|`bytes32`|Unique value to generate deterministic pool address| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`address`|Address of the newly deployed pool| + + +### allPoolsLength + +Get the length of `allPools` array. + + +```solidity +function allPoolsLength() external view returns (uint256); +``` +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`uint256`|`allPools` length.| + + +### getAllPoolsListSlice + +Get a slice of the deployed pools array. + + +```solidity +function getAllPoolsListSlice(uint256 _start, uint256 _end) external view returns (address[] memory); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_start`|`uint256`|Start index of the slice.| +|`_end`|`uint256`|End index of the slice.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`address[]`|An array containing the slice of the deployed pools.| + + +### checkEulerAccountOperators + +Validates operator authorization for euler account. First checks if the account has an existing operator +and ensures it is deauthorized. Then verifies the new pool is authorized as an operator. Finally, updates the +mapping to track the new pool as the account's operator. + + +```solidity +function checkEulerAccountOperators(address eulerAccount, address newPool) internal; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`eulerAccount`|`address`|The address of the euler account.| +|`newPool`|`address`|The address of the new pool.| + + +## Events +### PoolDeployed + +```solidity +event PoolDeployed( + address indexed asset0, + address indexed asset1, + address vault0, + address vault1, + uint256 indexed feeMultiplier, + address eulerAccount, + uint256 priceX, + uint256 priceY, + uint256 concentrationX, + uint256 concentrationY, + address pool +); +``` + +## Errors +### InvalidQuery + +```solidity +error InvalidQuery(); +``` + +### Unauthorized + +```solidity +error Unauthorized(); +``` + +### OldOperatorStillInstalled + +```solidity +error OldOperatorStillInstalled(); +``` + +### OperatorNotInstalled + +```solidity +error OperatorNotInstalled(); +``` + diff --git a/foundry-docs/src/src/EulerSwapPeriphery.sol/contract.EulerSwapPeriphery.md b/foundry-docs/src/src/EulerSwapPeriphery.sol/contract.EulerSwapPeriphery.md new file mode 100644 index 0000000..a262f00 --- /dev/null +++ b/foundry-docs/src/src/EulerSwapPeriphery.sol/contract.EulerSwapPeriphery.md @@ -0,0 +1,219 @@ +# EulerSwapPeriphery +[Git Source](https://github.com/euler-xyz/euler-maglev/blob/d6fc4adb9f1050f1348bfff5db3603f2482ba705/src/EulerSwapPeriphery.sol) + +**Inherits:** +[IEulerSwapPeriphery](/src/interfaces/IEulerSwapPeriphery.sol/interface.IEulerSwapPeriphery.md) + + +## Functions +### swapExactIn + +Swap `amountIn` of `tokenIn` for `tokenOut`, with at least `amountOutMin` received. + + +```solidity +function swapExactIn(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin) + external; +``` + +### swapExactOut + +Swap `amountOut` of `tokenOut` for `tokenIn`, with at most `amountInMax` paid. + + +```solidity +function swapExactOut(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut, uint256 amountInMax) + external; +``` + +### quoteExactInput + +How much `tokenOut` can I get for `amountIn` of `tokenIn`? + + +```solidity +function quoteExactInput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn) + external + view + returns (uint256); +``` + +### quoteExactOutput + +How much `tokenIn` do I need to get `amountOut` of `tokenOut`? + + +```solidity +function quoteExactOutput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut) + external + view + returns (uint256); +``` + +### swap + +*Internal function to execute a token swap through EulerSwap* + + +```solidity +function swap(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut) internal; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`eulerSwap`|`address`|The EulerSwap contract address to execute the swap through| +|`tokenIn`|`address`|The address of the input token being swapped| +|`tokenOut`|`address`|The address of the output token being received| +|`amountIn`|`uint256`|The amount of input tokens to swap| +|`amountOut`|`uint256`|The amount of output tokens to receive| + + +### computeQuote + +*Computes the quote for a swap by applying fees and validating state conditions* + +*Validates: +- EulerSwap operator is installed +- Token pair is supported +- Sufficient reserves exist +- Sufficient cash is available* + + +```solidity +function computeQuote(IEulerSwap eulerSwap, address tokenIn, address tokenOut, uint256 amount, bool exactIn) + internal + view + returns (uint256); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`eulerSwap`|`IEulerSwap`|The EulerSwap contract to quote from| +|`tokenIn`|`address`|The input token address| +|`tokenOut`|`address`|The output token address| +|`amount`|`uint256`|The amount to quote (input amount if exactIn=true, output amount if exactIn=false)| +|`exactIn`|`bool`|True if quoting for exact input amount, false if quoting for exact output amount| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`uint256`|The quoted amount (output amount if exactIn=true, input amount if exactIn=false)| + + +### binarySearch + +Binary searches for the output amount along a swap curve given input parameters + +*General-purpose routine for binary searching swapping curves. +Although some curves may have more efficient closed-form solutions, +this works with any monotonic curve.* + + +```solidity +function binarySearch( + IEulerSwap eulerSwap, + uint112 reserve0, + uint112 reserve1, + uint256 amount, + bool exactIn, + bool asset0IsInput +) internal view returns (uint256 output); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`eulerSwap`|`IEulerSwap`|The EulerSwap contract to search the curve for| +|`reserve0`|`uint112`|Current reserve of asset0 in the pool| +|`reserve1`|`uint112`|Current reserve of asset1 in the pool| +|`amount`|`uint256`|The input or output amount depending on exactIn| +|`exactIn`|`bool`|True if amount is input amount, false if amount is output amount| +|`asset0IsInput`|`bool`|True if asset0 is being input, false if asset1 is being input| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`output`|`uint256`|The calculated output amount from the binary search| + + +### fInverse + +Computes the inverse of the `f()` function for the EulerSwap liquidity curve. + +*Solves for `x` given `y` using the quadratic formula derived from the liquidity curve: +x = (-b + sqrt(b^2 + 4ac)) / 2a +Utilises mulDiv to avoid overflow and ensures precision with upward rounding.* + +**Notes:** +- precision: Uses rounding up to maintain precision in all calculations. + +- safety: FullMath handles potential overflow in the b^2 computation. + +- requirement: Input `y` must be strictly greater than `y0`; otherwise, the function will revert. + + +```solidity +function fInverse(uint256 y, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) + external + pure + returns (uint256); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`y`|`uint256`|The y-coordinate input value (must be greater than `y0`).| +|`px`|`uint256`|Price factor for the x-axis (scaled by 1e18, between 1e18 and 1e36).| +|`py`|`uint256`|Price factor for the y-axis (scaled by 1e18, between 1e18 and 1e36).| +|`x0`|`uint256`|Reference x-value on the liquidity curve (≤ 2^112 - 1).| +|`y0`|`uint256`|Reference y-value on the liquidity curve (≤ 2^112 - 1).| +|`c`|`uint256`|Curve parameter shaping liquidity concentration (scaled by 1e18, between 0 and 1e18).| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`uint256`|x The computed x-coordinate on the liquidity curve.| + + +## Errors +### UnsupportedPair + +```solidity +error UnsupportedPair(); +``` + +### OperatorNotInstalled + +```solidity +error OperatorNotInstalled(); +``` + +### InsufficientReserves + +```solidity +error InsufficientReserves(); +``` + +### InsufficientCash + +```solidity +error InsufficientCash(); +``` + +### AmountOutLessThanMin + +```solidity +error AmountOutLessThanMin(); +``` + +### AmountInMoreThanMax + +```solidity +error AmountInMoreThanMax(); +``` + diff --git a/foundry-docs/src/src/README.md b/foundry-docs/src/src/README.md new file mode 100644 index 0000000..48c4e58 --- /dev/null +++ b/foundry-docs/src/src/README.md @@ -0,0 +1,7 @@ + + +# Contents +- [interfaces](/src/interfaces) +- [EulerSwap](EulerSwap.sol/contract.EulerSwap.md) +- [EulerSwapFactory](EulerSwapFactory.sol/contract.EulerSwapFactory.md) +- [EulerSwapPeriphery](EulerSwapPeriphery.sol/contract.EulerSwapPeriphery.md) diff --git a/foundry-docs/src/src/interfaces/IEulerSwap.sol/interface.IEulerSwap.md b/foundry-docs/src/src/interfaces/IEulerSwap.sol/interface.IEulerSwap.md new file mode 100644 index 0000000..cda0611 --- /dev/null +++ b/foundry-docs/src/src/interfaces/IEulerSwap.sol/interface.IEulerSwap.md @@ -0,0 +1,177 @@ +# IEulerSwap +[Git Source](https://github.com/euler-xyz/euler-maglev/blob/d6fc4adb9f1050f1348bfff5db3603f2482ba705/src/interfaces/IEulerSwap.sol) + + +## Functions +### swap + +Optimistically sends the requested amounts of tokens to the `to` +address, invokes `uniswapV2Call` callback on `to` (if `data` was provided), +and then verifies that a sufficient amount of tokens were transferred to +satisfy the swapping curve invariant. + + +```solidity +function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; +``` + +### activate + +Approves the vaults to access the EulerSwap instance's tokens, and enables +vaults as collateral. Can be invoked by anybody, and is harmless if invoked again. +Calling this function is optional: EulerSwap can be activated on the first swap. + + +```solidity +function activate() external; +``` + +### verify + +Function that defines the shape of the swapping curve. Returns true iff +the specified reserve amounts would be acceptable (ie it is above and to-the-right +of the swapping curve). + + +```solidity +function verify(uint256 newReserve0, uint256 newReserve1) external view returns (bool); +``` + +### EVC + +Returns the address of the Ethereum Vault Connector (EVC) used by this contract. + + +```solidity +function EVC() external view returns (address); +``` +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`address`|The address of the EVC contract.| + + +### curve + + +```solidity +function curve() external view returns (bytes32); +``` + +### vault0 + + +```solidity +function vault0() external view returns (address); +``` + +### vault1 + + +```solidity +function vault1() external view returns (address); +``` + +### asset0 + + +```solidity +function asset0() external view returns (address); +``` + +### asset1 + + +```solidity +function asset1() external view returns (address); +``` + +### eulerAccount + + +```solidity +function eulerAccount() external view returns (address); +``` + +### initialReserve0 + + +```solidity +function initialReserve0() external view returns (uint112); +``` + +### initialReserve1 + + +```solidity +function initialReserve1() external view returns (uint112); +``` + +### feeMultiplier + + +```solidity +function feeMultiplier() external view returns (uint256); +``` + +### getReserves + + +```solidity +function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 status); +``` + +### priceX + + +```solidity +function priceX() external view returns (uint256); +``` + +### priceY + + +```solidity +function priceY() external view returns (uint256); +``` + +### concentrationX + + +```solidity +function concentrationX() external view returns (uint256); +``` + +### concentrationY + + +```solidity +function concentrationY() external view returns (uint256); +``` + +## Structs +### Params + +```solidity +struct Params { + address vault0; + address vault1; + address eulerAccount; + uint112 debtLimit0; + uint112 debtLimit1; + uint256 fee; +} +``` + +### CurveParams + +```solidity +struct CurveParams { + uint256 priceX; + uint256 priceY; + uint256 concentrationX; + uint256 concentrationY; +} +``` + diff --git a/foundry-docs/src/src/interfaces/IEulerSwapFactory.sol/interface.IEulerSwapFactory.md b/foundry-docs/src/src/interfaces/IEulerSwapFactory.sol/interface.IEulerSwapFactory.md new file mode 100644 index 0000000..3743ef0 --- /dev/null +++ b/foundry-docs/src/src/interfaces/IEulerSwapFactory.sol/interface.IEulerSwapFactory.md @@ -0,0 +1,35 @@ +# IEulerSwapFactory +[Git Source](https://github.com/euler-xyz/euler-maglev/blob/d6fc4adb9f1050f1348bfff5db3603f2482ba705/src/interfaces/IEulerSwapFactory.sol) + + +## Functions +### deployPool + + +```solidity +function deployPool(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams, bytes32 salt) + external + returns (address); +``` + +### allPools + + +```solidity +function allPools(uint256 index) external view returns (address); +``` + +### allPoolsLength + + +```solidity +function allPoolsLength() external view returns (uint256); +``` + +### getAllPoolsListSlice + + +```solidity +function getAllPoolsListSlice(uint256 start, uint256 end) external view returns (address[] memory); +``` + diff --git a/foundry-docs/src/src/interfaces/IEulerSwapPeriphery.sol/interface.IEulerSwapPeriphery.md b/foundry-docs/src/src/interfaces/IEulerSwapPeriphery.sol/interface.IEulerSwapPeriphery.md new file mode 100644 index 0000000..898fa72 --- /dev/null +++ b/foundry-docs/src/src/interfaces/IEulerSwapPeriphery.sol/interface.IEulerSwapPeriphery.md @@ -0,0 +1,49 @@ +# IEulerSwapPeriphery +[Git Source](https://github.com/euler-xyz/euler-maglev/blob/d6fc4adb9f1050f1348bfff5db3603f2482ba705/src/interfaces/IEulerSwapPeriphery.sol) + + +## Functions +### swapExactIn + +Swap `amountIn` of `tokenIn` for `tokenOut`, with at least `amountOutMin` received. + + +```solidity +function swapExactIn(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin) + external; +``` + +### swapExactOut + +Swap `amountOut` of `tokenOut` for `tokenIn`, with at most `amountInMax` paid. + + +```solidity +function swapExactOut(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut, uint256 amountInMax) + external; +``` + +### quoteExactInput + +How much `tokenOut` can I get for `amountIn` of `tokenIn`? + + +```solidity +function quoteExactInput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn) + external + view + returns (uint256); +``` + +### quoteExactOutput + +How much `tokenIn` do I need to get `amountOut` of `tokenOut`? + + +```solidity +function quoteExactOutput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut) + external + view + returns (uint256); +``` + diff --git a/foundry-docs/src/src/interfaces/IUniswapV2Callee.sol/interface.IUniswapV2Callee.md b/foundry-docs/src/src/interfaces/IUniswapV2Callee.sol/interface.IUniswapV2Callee.md new file mode 100644 index 0000000..811ac44 --- /dev/null +++ b/foundry-docs/src/src/interfaces/IUniswapV2Callee.sol/interface.IUniswapV2Callee.md @@ -0,0 +1,12 @@ +# IUniswapV2Callee +[Git Source](https://github.com/euler-xyz/euler-maglev/blob/d6fc4adb9f1050f1348bfff5db3603f2482ba705/src/interfaces/IUniswapV2Callee.sol) + + +## Functions +### uniswapV2Call + + +```solidity +function uniswapV2Call(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external; +``` + diff --git a/foundry-docs/src/src/interfaces/README.md b/foundry-docs/src/src/interfaces/README.md new file mode 100644 index 0000000..fdfceb3 --- /dev/null +++ b/foundry-docs/src/src/interfaces/README.md @@ -0,0 +1,7 @@ + + +# Contents +- [IEulerSwap](IEulerSwap.sol/interface.IEulerSwap.md) +- [IEulerSwapFactory](IEulerSwapFactory.sol/interface.IEulerSwapFactory.md) +- [IEulerSwapPeriphery](IEulerSwapPeriphery.sol/interface.IEulerSwapPeriphery.md) +- [IUniswapV2Callee](IUniswapV2Callee.sol/interface.IUniswapV2Callee.md) diff --git a/foundry.toml b/foundry.toml index 4c9b590..2449f10 100644 --- a/foundry.toml +++ b/foundry.toml @@ -7,4 +7,8 @@ optimizer = true optimizer_runs = 10000 gas_reports = ["*"] +[doc] +out = "foundry-docs/" +title = "Euler Swap Contracts Documentation" + # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options From 2fb7b0763ba44d94281a2403cad190ad8277340f Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 5 Mar 2025 01:12:39 -0500 Subject: [PATCH 188/312] factor duplicated approval/permit2 code --- src/EulerSwap.sol | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 87cecc8..792423f 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -164,24 +164,21 @@ contract EulerSwap is IEulerSwap, EVCUtil { require(status != 2, Locked()); status = 1; - address permit2 = IEVault(vault0).permit2Address(); - if (permit2 == address(0)) { - IERC20(asset0).forceApprove(vault0, type(uint256).max); - } else { - IERC20(asset0).forceApprove(permit2, type(uint256).max); - IAllowanceTransfer(permit2).approve(asset0, vault0, type(uint160).max, type(uint48).max); - } + approveVault(asset0, vault0); + approveVault(asset1, vault1); + + IEVC(evc).enableCollateral(eulerAccount, vault0); + IEVC(evc).enableCollateral(eulerAccount, vault1); + } - permit2 = IEVault(vault1).permit2Address(); + function approveVault(address asset, address vault) internal { + address permit2 = IEVault(vault).permit2Address(); if (permit2 == address(0)) { - IERC20(asset1).forceApprove(vault1, type(uint256).max); + IERC20(asset).forceApprove(vault, type(uint256).max); } else { - IERC20(asset1).forceApprove(permit2, type(uint256).max); - IAllowanceTransfer(permit2).approve(asset1, vault1, type(uint160).max, type(uint48).max); + IERC20(asset).forceApprove(permit2, type(uint256).max); + IAllowanceTransfer(permit2).approve(asset, vault, type(uint160).max, type(uint48).max); } - - IEVC(evc).enableCollateral(eulerAccount, vault0); - IEVC(evc).enableCollateral(eulerAccount, vault1); } /// @inheritdoc IEulerSwap From 6e3c66adaabba7280d75f599be97a894e2f1b42e Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 5 Mar 2025 01:16:00 -0500 Subject: [PATCH 189/312] why bother hashing? it's always going to be a short descriptor anyway --- src/EulerSwap.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 87cecc8..5a922e2 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -14,7 +14,7 @@ import {Math} from "openzeppelin-contracts/utils/math/Math.sol"; contract EulerSwap is IEulerSwap, EVCUtil { using SafeERC20 for IERC20; - bytes32 public constant curve = keccak256("EulerSwap v1"); + bytes32 public constant curve = bytes32("EulerSwap v1"); address public immutable vault0; address public immutable vault1; From a0723b786a86bcc5c356620d9a8a2a9a63e7aa35 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 5 Mar 2025 15:26:45 +0900 Subject: [PATCH 190/312] chore: delete errors.md --- docs/errors.md | 47 ----------------------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 docs/errors.md diff --git a/docs/errors.md b/docs/errors.md deleted file mode 100644 index 4de54ec..0000000 --- a/docs/errors.md +++ /dev/null @@ -1,47 +0,0 @@ -# Errors - -## Introduction - -The EulerSwap smart contracts throw errors that can help developers debug why EulerSwap instances are failing to provide quotes, satisfy swaps, rebalance, and more. In some cases these errors emerge directly from the EulerSwap smart contracts themselves, while errors can also come from lower level dependencies, such as the Euler Vault Kit (EVK) and Ethereum Vault Connector (EVC). Each error is listed here with its name and a description of when and why it might occur. - -## Summary - -### E_AccountLiquidity - -**Description:** This error is thrown when the liquidity provider account on Euler does not have sufficient liquidity to perform a particular action, such as borrowing or swapping assets. It typically indicates that the collateral value is not enough to cover the desired transaction within the EVK module. - -### E_AmountTooLargeToEncode - -**Description:** TODO. - -### E_BadAddress - -**Description:** This error is triggered when an invalid or null address is provided as an input. It is commonly associated with interactions where a recipient, sender, or contract address must be validated before proceeding with a transaction. - -### E_BadAssetReceiver - -**Description:** Thrown when an asset is directed to an unintended or incompatible receiver contract. This error often prevents token transfers to addresses that do not implement necessary interfaces or are not approved within the EVK and EVC architecture. - -### E_BadBorrowCap - -**Description:** This error indicates that the specified borrowing cap for an asset is invalid, either being too high or too low according to protocol parameters. It helps maintain stability by enforcing borrowing limits in the EVK. - -### E_BadCollateral - -**Description:** Raised when an invalid asset is proposed as collateral in a transaction. The EVK system uses this error to ensure only approved and properly configured assets are used to back borrowing positions. - -### E_BadFee - -**Description:** This error is related to fee calculations within the EulerSwap or associated periphery contracts. It ensures that any fee applied during swaps or vault interactions is within the acceptable bounds set by governance or protocol parameters. - -### E_BadMaxLiquidationDiscount - -**Description:** Thrown when an invalid maximum liquidation discount is set. Liquidation discounts are critical for maintaining incentives for liquidators while protecting the protocol from excessive losses during liquidation events. - -### E_BadSharesOwner - -**Description:** This error indicates that the shares of a vault or liquidity pool are owned by an unexpected or unauthorised entity. It ensures that share ownership is consistent with the expected state of the EVK or EVC modules. - -## Further reading - -For more information, refer to the EulerSwap [White Paper](docs/whitepaper/EulerSwap_White_Paper.pdf) and the smart contract source code. From 3035a513c12cedd7eff996053bb018612ac8fc33 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 5 Mar 2025 15:28:18 +0900 Subject: [PATCH 191/312] chore: remove events.md --- docs/events.md | 143 ------------------------------------------------- 1 file changed, 143 deletions(-) delete mode 100644 docs/events.md diff --git a/docs/events.md b/docs/events.md deleted file mode 100644 index b660e3b..0000000 --- a/docs/events.md +++ /dev/null @@ -1,143 +0,0 @@ -# Events - -## Introduction - -The EulerSwap smart contracts emit several key event types to notify off-chain systems (e.g., frontends, analytics tools) of important state changes. These events facilitate transparency, integration with external systems, and effective monitoring of the protocol's behavior. - -Events such as EulerSwapCreated and PoolDeployed are particularly useful for solvers and aggregators. These tools can track new pool creations, allowing them to dynamically update their routing algorithms and ensure trades are optimally routed through EulerSwap pools, enhancing liquidity and trading efficiency. - -### Summary - -| **Event** | **Contract** | **Purpose** | **Use Case** | -| ------------------ | ------------------ | ----------------------------------------------------- | ------------------------------------- | -| `AddLiquidity` | `EulerSwap` | Emitted when liquidity is added to the pool | Track liquidity inflows | -| `RemoveLiquidity` | `EulerSwap` | Emitted when liquidity is removed from the pool | Monitor liquidity outflows | -| `Swap` | `EulerSwap` | Emitted during token swaps | Trading analytics and UIs | -| `CollectFees` | `EulerSwap` | Emitted when trading fees are collected | Revenue and protocol fee management | -| `StatusChanged` | `EulerSwap` | Signals a change in the contract's operational status | DApp integration and state management | -| `DebtLimitUpdated` | `EulerSwap` | Emitted when debt limits for assets are modified | Risk management and protocol settings | -| `ErrorOccurred` | `EulerSwap` | Captures errors and exceptions | Debugging and transaction monitoring | -| `EulerSwapCreated` | `EulerSwapFactory` | Emitted when a new `EulerSwap` instance is created | Track creation of new liquidity pools | -| `PoolDeployed` | `EulerSwapFactory` | Indicates when a new liquidity pool is deployed | Detecting and listing new pools | - -## Details - -### Events in `EulerSwap.sol` - -#### Liquidity management events - -##### `AddLiquidity` - -```solidity -event AddLiquidity(address indexed provider, uint256 amount0, uint256 amount1); -``` - -- **Purpose:** Emitted when liquidity is added to the pool. -- **Parameters:** - - `provider`: Address adding liquidity. - - `amount0`, `amount1`: Quantities of `asset0` and `asset1` added. -- **Use Case:** Helps liquidity providers and analytics tools track liquidity inflows. - -##### `RemoveLiquidity` - -```solidity -event RemoveLiquidity(address indexed provider, uint256 amount0, uint256 amount1); -``` - -- **Purpose:** Indicates when liquidity is withdrawn from the pool. -- **Parameters:** - - `provider`: Address removing liquidity. - - `amount0`, `amount1`: Quantities of `asset0` and `asset1` withdrawn. -- **Use Case:** Updates frontends and liquidity dashboards with outflows. - -#### Trading events - -##### `Swap` - -```solidity -event Swap(address indexed trader, address indexed assetIn, address indexed assetOut, uint256 amountIn, uint256 amountOut); -``` - -- **Purpose:** Emitted during token swaps. -- **Parameters:** - - `trader`: Address executing the swap. - - `assetIn`, `assetOut`: Assets being swapped. - - `amountIn`, `amountOut`: Amounts involved in the swap. -- **Use Case:** Crucial for trade analytics, swap history, and integration with trading UIs. - -#### Fee & accounting events - -##### `CollectFees` - -```solidity -event CollectFees(address indexed collector, uint256 fees0, uint256 fees1); -``` - -- **Purpose:** Tracks when trading fees are collected. -- **Parameters:** - - `collector`: Address receiving the fees. - - `fees0`, `fees1`: Fees collected in `asset0` and `asset1`. -- **Use Case:** Important for revenue tracking and protocol fee management. - -#### Administrative & status events - -##### `StatusChanged` - -```solidity -event StatusChanged(uint32 oldStatus, uint32 newStatus); -``` - -- **Purpose:** Signals a change in the contract's operational status. -- **Parameters:** - - `oldStatus`, `newStatus`: Numerical representation of the contract status (e.g., `0 = unactivated`, `1 = unlocked`, `2 = locked`). -- **Use Case:** Enables dApps to adjust their behavior based on the contract state. - -##### `DebtLimitUpdated` - -```solidity -event DebtLimitUpdated(uint112 newDebtLimit0, uint112 newDebtLimit1); -``` - -- **Purpose:** Notifies when the debt limits for the assets are updated. -- **Parameters:** - - `newDebtLimit0`, `newDebtLimit1`: New debt limits for `asset0` and `asset1`. -- **Use Case:** Supports risk management and off-chain monitoring of protocol settings. - -### Events in `EulerSwapFactory.sol` - -##### `EulerSwapCreated` - -```solidity -event EulerSwapCreated(address indexed asset0, address indexed asset1); -``` - -- **Purpose:** Emitted when a new `EulerSwap` instance is created. -- **Parameters:** - - `asset0`, `asset1`: Addresses of the tokens in the newly created trading pair. -- **Use Case:** Useful for tracking the creation of new liquidity pools and integrating with factory-based analytics. - -##### `PoolDeployed` - -```solidity -event PoolDeployed(address indexed pool, address indexed asset0, address indexed asset1); -``` - -- **Purpose:** Indicates when a new liquidity pool is deployed by the `EulerSwapFactory`. -- **Parameters:** - - `pool`: Address of the newly deployed pool. - - `asset0`, `asset1`: Addresses of the tokens in the pool. -- **Use Case:** Essential for detecting new pool deployments, often used by front-end interfaces to list available pools dynamically. - -### Error handling events - -##### `ErrorOccurred` - -```solidity -event ErrorOccurred(address indexed account, string message); -``` - -- **Purpose:** Emitted when an error or unexpected condition occurs. -- **Parameters:** - - `account`: Address involved in the error. - - `message`: Description of the error. -- **Use Case:** Useful for debugging and alerting systems about failed transactions or invalid operations. From bb2a0079880aeb8631360de65ffd2e0cd836d78a Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 5 Mar 2025 16:22:00 +0900 Subject: [PATCH 192/312] optimize isAccountOperatorAuthorized() call --- src/EulerSwapPeriphery.sol | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index ebce34d..9265b90 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -239,16 +239,19 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { view returns (uint256 inLimit, uint256 outLimit) { + if ( + !IEVC(IEulerSwap(eulerSwap).EVC()).isAccountOperatorAuthorized( + IEulerSwap(eulerSwap).eulerAccount(), eulerSwap + ) + ) return (0, 0); + return _getLimits(IEulerSwap(eulerSwap), checkTokens(IEulerSwap(eulerSwap), tokenIn, tokenOut)); } function _getLimits(IEulerSwap es, bool asset0IsInput) internal view returns (uint256 inLimit, uint256 outLimit) { - if (!IEVC(es.EVC()).isAccountOperatorAuthorized(es.eulerAccount(), address(es))) return (0, 0); - inLimit = outLimit = type(uint112).max; // Supply caps on input - { IEVault vault = IEVault(asset0IsInput ? es.vault0() : es.vault1()); uint256 maxDeposit = vault.debtOf(es.eulerAccount()) + vault.maxDeposit(es.eulerAccount()); @@ -256,7 +259,6 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { } // Remaining reserves of output - { (uint112 reserve0, uint112 reserve1,) = es.getReserves(); uint112 reserveLimit = asset0IsInput ? reserve1 : reserve0; @@ -264,7 +266,6 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { } // Remaining cash and borrow caps in output - { IEVault vault = IEVault(asset0IsInput ? es.vault1() : es.vault0()); From f49b4fe3facd571db688005d6b3cfc0487f8462e Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 5 Mar 2025 16:27:14 +0900 Subject: [PATCH 193/312] optimize .eulerAccount() calls --- src/EulerSwapPeriphery.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index 9265b90..bc5703b 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -250,11 +250,11 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { function _getLimits(IEulerSwap es, bool asset0IsInput) internal view returns (uint256 inLimit, uint256 outLimit) { inLimit = outLimit = type(uint112).max; - + address eulerAccount = es.eulerAccount(); // Supply caps on input { IEVault vault = IEVault(asset0IsInput ? es.vault0() : es.vault1()); - uint256 maxDeposit = vault.debtOf(es.eulerAccount()) + vault.maxDeposit(es.eulerAccount()); + uint256 maxDeposit = vault.debtOf(eulerAccount) + vault.maxDeposit(eulerAccount); if (maxDeposit < inLimit) inLimit = maxDeposit; } @@ -276,7 +276,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { uint256 maxWithdraw = decodeCap(uint256(borrowCap)); maxWithdraw = vault.totalBorrows() > maxWithdraw ? 0 : maxWithdraw - vault.totalBorrows(); if (maxWithdraw > cash) maxWithdraw = cash; - maxWithdraw += vault.convertToAssets(vault.balanceOf(es.eulerAccount())); + maxWithdraw += vault.convertToAssets(vault.balanceOf(eulerAccount)); if (maxWithdraw < outLimit) outLimit = maxWithdraw; } } From 56e74007f78c45ccace1dde89b0f94a6d221fd21 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 5 Mar 2025 16:47:16 +0900 Subject: [PATCH 194/312] optimize vault0() & vaulr1() calls --- src/EulerSwapPeriphery.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index bc5703b..b2be5e0 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -251,9 +251,10 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { function _getLimits(IEulerSwap es, bool asset0IsInput) internal view returns (uint256 inLimit, uint256 outLimit) { inLimit = outLimit = type(uint112).max; address eulerAccount = es.eulerAccount(); + (IEVault vault0, IEVault vault1) = (IEVault(es.vault0()), IEVault(es.vault1())); // Supply caps on input { - IEVault vault = IEVault(asset0IsInput ? es.vault0() : es.vault1()); + IEVault vault = IEVault(asset0IsInput ? vault0 : vault1); uint256 maxDeposit = vault.debtOf(eulerAccount) + vault.maxDeposit(eulerAccount); if (maxDeposit < inLimit) inLimit = maxDeposit; } @@ -267,7 +268,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { // Remaining cash and borrow caps in output { - IEVault vault = IEVault(asset0IsInput ? es.vault1() : es.vault0()); + IEVault vault = IEVault(asset0IsInput ? vault1 : vault0); uint256 cash = vault.cash(); if (cash < outLimit) outLimit = cash; From 065cf6c25b7b99ff64e337c7d4403af4c9e8b318 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 5 Mar 2025 16:53:28 +0900 Subject: [PATCH 195/312] clean --- src/EulerSwapPeriphery.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index b2be5e0..cd3b0f9 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -254,7 +254,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { (IEVault vault0, IEVault vault1) = (IEVault(es.vault0()), IEVault(es.vault1())); // Supply caps on input { - IEVault vault = IEVault(asset0IsInput ? vault0 : vault1); + IEVault vault = (asset0IsInput ? vault0 : vault1); uint256 maxDeposit = vault.debtOf(eulerAccount) + vault.maxDeposit(eulerAccount); if (maxDeposit < inLimit) inLimit = maxDeposit; } @@ -268,7 +268,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { // Remaining cash and borrow caps in output { - IEVault vault = IEVault(asset0IsInput ? vault1 : vault0); + IEVault vault = (asset0IsInput ? vault1 : vault0); uint256 cash = vault.cash(); if (cash < outLimit) outLimit = cash; From 60245322722aae3a297dd37ec4b85b766610cee3 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 5 Mar 2025 17:15:13 +0900 Subject: [PATCH 196/312] clean --- src/EulerSwapPeriphery.sol | 154 ++++++++++++++----------- src/interfaces/IEulerSwapPeriphery.sol | 30 +++++ 2 files changed, 117 insertions(+), 67 deletions(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index cd3b0f9..30d43c4 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -56,6 +56,56 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { return computeQuote(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountOut, false); } + /// @inheritdoc IEulerSwapPeriphery + function getLimits(address eulerSwap, address tokenIn, address tokenOut) + external + view + returns (uint256 inLimit, uint256 outLimit) + { + if ( + !IEVC(IEulerSwap(eulerSwap).EVC()).isAccountOperatorAuthorized( + IEulerSwap(eulerSwap).eulerAccount(), eulerSwap + ) + ) return (0, 0); + + return calcLimits(IEulerSwap(eulerSwap), checkTokens(IEulerSwap(eulerSwap), tokenIn, tokenOut)); + } + + /// @inheritdoc IEulerSwapPeriphery + function fInverse(uint256 y, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) + external + pure + returns (uint256) + { + // A component of the quadratic formula: a = 2 * c + uint256 A = 2 * c; + + // B component of the quadratic formula + int256 B = int256((px * (y - y0) + py - 1) / py) - int256((x0 * (2 * c - 1e18) + 1e18 - 1) / 1e18); + + // B^2 component, using FullMath for overflow safety + uint256 absB = B < 0 ? uint256(-B) : uint256(B); + uint256 squaredB = Math.mulDiv(absB, absB, 1e18, Math.Rounding.Ceil); + + // 4 * A * C component of the quadratic formula + uint256 AC4 = Math.mulDiv( + Math.mulDiv(4 * c, (1e18 - c), 1e18, Math.Rounding.Ceil), + Math.mulDiv(x0, x0, 1e18, Math.Rounding.Ceil), + 1e18, + Math.Rounding.Ceil + ); + + // Discriminant: b^2 + 4ac, scaled up to maintain precision + uint256 discriminant = (squaredB + AC4) * 1e18; + + // Square root of the discriminant (rounded up) + uint256 sqrt = Math.sqrt(discriminant); + sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; + + // Compute and return x = fInverse(y) using the quadratic formula + return Math.mulDiv(uint256(int256(sqrt) - B), 1e18, A, Math.Rounding.Ceil); + } + /// @dev Internal function to execute a token swap through EulerSwap /// @param eulerSwap The EulerSwap contract address to execute the swap through /// @param tokenIn The address of the input token being swapped @@ -101,7 +151,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { if (exactIn) amount = amount * feeMultiplier / 1e18; bool asset0IsInput = checkTokens(eulerSwap, tokenIn, tokenOut); - (uint256 inLimit, uint256 outLimit) = _getLimits(eulerSwap, asset0IsInput); + (uint256 inLimit, uint256 outLimit) = calcLimits(eulerSwap, asset0IsInput); uint256 quote = binarySearch(eulerSwap, reserve0, reserve1, amount, exactIn, asset0IsInput); @@ -181,75 +231,22 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { } /** - * @notice Computes the inverse of the `f()` function for the EulerSwap liquidity curve. - * @dev Solves for `x` given `y` using the quadratic formula derived from the liquidity curve: - * x = (-b + sqrt(b^2 + 4ac)) / 2a - * Utilises mulDiv to avoid overflow and ensures precision with upward rounding. - * - * @param y The y-coordinate input value (must be greater than `y0`). - * @param px Price factor for the x-axis (scaled by 1e18, between 1e18 and 1e36). - * @param py Price factor for the y-axis (scaled by 1e18, between 1e18 and 1e36). - * @param x0 Reference x-value on the liquidity curve (≤ 2^112 - 1). - * @param y0 Reference y-value on the liquidity curve (≤ 2^112 - 1). - * @param c Curve parameter shaping liquidity concentration (scaled by 1e18, between 0 and 1e18). - * - * @return x The computed x-coordinate on the liquidity curve. + * @notice Calculates the maximum input and output amounts for a swap based on protocol constraints + * @dev Determines limits by checking multiple factors: + * 1. Supply caps and existing debt for the input token + * 2. Available reserves in the EulerSwap for the output token + * 3. Available cash and borrow caps for the output token + * 4. Account balances in the respective vaults * - * @custom:precision Uses rounding up to maintain precision in all calculations. - * @custom:safety FullMath handles potential overflow in the b^2 computation. - * @custom:requirement Input `y` must be strictly greater than `y0`; otherwise, the function will revert. + * @param es The EulerSwap contract to calculate limits for + * @param asset0IsInput Boolean indicating whether asset0 (true) or asset1 (false) is the input token + * @return uint256 Maximum amount of input token that can be deposited + * @return uint256 Maximum amount of output token that can be withdrawn */ - function fInverse(uint256 y, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) - external - pure - returns (uint256) - { - // A component of the quadratic formula: a = 2 * c - uint256 A = 2 * c; - - // B component of the quadratic formula - int256 B = int256((px * (y - y0) + py - 1) / py) - int256((x0 * (2 * c - 1e18) + 1e18 - 1) / 1e18); - - // B^2 component, using FullMath for overflow safety - uint256 absB = B < 0 ? uint256(-B) : uint256(B); - uint256 squaredB = Math.mulDiv(absB, absB, 1e18, Math.Rounding.Ceil); + function calcLimits(IEulerSwap es, bool asset0IsInput) internal view returns (uint256, uint256) { + uint256 inLimit = type(uint112).max; + uint256 outLimit = type(uint112).max; - // 4 * A * C component of the quadratic formula - uint256 AC4 = Math.mulDiv( - Math.mulDiv(4 * c, (1e18 - c), 1e18, Math.Rounding.Ceil), - Math.mulDiv(x0, x0, 1e18, Math.Rounding.Ceil), - 1e18, - Math.Rounding.Ceil - ); - - // Discriminant: b^2 + 4ac, scaled up to maintain precision - uint256 discriminant = (squaredB + AC4) * 1e18; - - // Square root of the discriminant (rounded up) - uint256 sqrt = Math.sqrt(discriminant); - sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; - - // Compute and return x = fInverse(y) using the quadratic formula - return Math.mulDiv(uint256(int256(sqrt) - B), 1e18, A, Math.Rounding.Ceil); - } - - /// @notice Max amount the pool can buy of tokenIn and sell of tokenOut - function getLimits(address eulerSwap, address tokenIn, address tokenOut) - external - view - returns (uint256 inLimit, uint256 outLimit) - { - if ( - !IEVC(IEulerSwap(eulerSwap).EVC()).isAccountOperatorAuthorized( - IEulerSwap(eulerSwap).eulerAccount(), eulerSwap - ) - ) return (0, 0); - - return _getLimits(IEulerSwap(eulerSwap), checkTokens(IEulerSwap(eulerSwap), tokenIn, tokenOut)); - } - - function _getLimits(IEulerSwap es, bool asset0IsInput) internal view returns (uint256 inLimit, uint256 outLimit) { - inLimit = outLimit = type(uint112).max; address eulerAccount = es.eulerAccount(); (IEVault vault0, IEVault vault1) = (IEVault(es.vault0()), IEVault(es.vault1())); // Supply caps on input @@ -280,8 +277,22 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { maxWithdraw += vault.convertToAssets(vault.balanceOf(eulerAccount)); if (maxWithdraw < outLimit) outLimit = maxWithdraw; } + + return (inLimit, outLimit); } + /** + * @notice Decodes a compact-format cap value to its actual numerical value + * @dev The cap uses a compact-format where: + * - If amountCap == 0, there's no cap (returns max uint256) + * - Otherwise, the lower 6 bits represent the exponent (10^exp) + * - The upper bits (>> 6) represent the mantissa + * - The formula is: (10^exponent * mantissa) / 100 + * @param amountCap The compact-format cap value to decode + * @return The actual numerical cap value (type(uint256).max if uncapped) + * @custom:security Uses unchecked math for gas optimization as calculations cannot overflow: + * maximum possible value 10^(2^6-1) * (2^10-1) ≈ 1.023e+66 < 2^256 + */ function decodeCap(uint256 amountCap) internal pure returns (uint256) { if (amountCap == 0) return type(uint256).max; @@ -292,6 +303,15 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { } } + /** + * @notice Verifies that the given tokens are supported by the EulerSwap pool and determines swap direction + * @dev Returns a boolean indicating whether the input token is asset0 (true) or asset1 (false) + * @param eulerSwap The EulerSwap pool contract to check against + * @param tokenIn The input token address for the swap + * @param tokenOut The output token address for the swap + * @return asset0IsInput True if tokenIn is asset0 and tokenOut is asset1, false if reversed + * @custom:error UnsupportedPair Thrown if the token pair is not supported by the EulerSwap pool + */ function checkTokens(IEulerSwap eulerSwap, address tokenIn, address tokenOut) internal view diff --git a/src/interfaces/IEulerSwapPeriphery.sol b/src/interfaces/IEulerSwapPeriphery.sol index 645bca7..ad5a7d7 100644 --- a/src/interfaces/IEulerSwapPeriphery.sol +++ b/src/interfaces/IEulerSwapPeriphery.sol @@ -21,4 +21,34 @@ interface IEulerSwapPeriphery { external view returns (uint256); + + /// @notice Max amount the pool can buy of tokenIn and sell of tokenOut + function getLimits(address eulerSwap, address tokenIn, address tokenOut) + external + view + returns (uint256 inLimit, uint256 outLimit); + + /** + * @notice Computes the inverse of the `f()` function for the EulerSwap liquidity curve. + * @dev Solves for `x` given `y` using the quadratic formula derived from the liquidity curve: + * x = (-b + sqrt(b^2 + 4ac)) / 2a + * Utilises mulDiv to avoid overflow and ensures precision with upward rounding. + * + * @param y The y-coordinate input value (must be greater than `y0`). + * @param px Price factor for the x-axis (scaled by 1e18, between 1e18 and 1e36). + * @param py Price factor for the y-axis (scaled by 1e18, between 1e18 and 1e36). + * @param x0 Reference x-value on the liquidity curve (≤ 2^112 - 1). + * @param y0 Reference y-value on the liquidity curve (≤ 2^112 - 1). + * @param c Curve parameter shaping liquidity concentration (scaled by 1e18, between 0 and 1e18). + * + * @return x The computed x-coordinate on the liquidity curve. + * + * @custom:precision Uses rounding up to maintain precision in all calculations. + * @custom:safety FullMath handles potential overflow in the b^2 computation. + * @custom:requirement Input `y` must be strictly greater than `y0`; otherwise, the function will revert. + */ + function fInverse(uint256 y, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) + external + pure + returns (uint256); } From 2c9c24d436f3a37121e05191c28fda0565921cba Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 5 Mar 2025 17:17:50 +0900 Subject: [PATCH 197/312] clean --- src/EulerSwapPeriphery.sol | 6 +----- src/interfaces/IEulerSwapPeriphery.sol | 5 +---- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index 30d43c4..f6ec589 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -57,11 +57,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { } /// @inheritdoc IEulerSwapPeriphery - function getLimits(address eulerSwap, address tokenIn, address tokenOut) - external - view - returns (uint256 inLimit, uint256 outLimit) - { + function getLimits(address eulerSwap, address tokenIn, address tokenOut) external view returns (uint256, uint256) { if ( !IEVC(IEulerSwap(eulerSwap).EVC()).isAccountOperatorAuthorized( IEulerSwap(eulerSwap).eulerAccount(), eulerSwap diff --git a/src/interfaces/IEulerSwapPeriphery.sol b/src/interfaces/IEulerSwapPeriphery.sol index ad5a7d7..72cd76f 100644 --- a/src/interfaces/IEulerSwapPeriphery.sol +++ b/src/interfaces/IEulerSwapPeriphery.sol @@ -23,10 +23,7 @@ interface IEulerSwapPeriphery { returns (uint256); /// @notice Max amount the pool can buy of tokenIn and sell of tokenOut - function getLimits(address eulerSwap, address tokenIn, address tokenOut) - external - view - returns (uint256 inLimit, uint256 outLimit); + function getLimits(address eulerSwap, address tokenIn, address tokenOut) external view returns (uint256, uint256); /** * @notice Computes the inverse of the `f()` function for the EulerSwap liquidity curve. From b7e7c609e9f532416bccda3011a299c4bfe061bf Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 5 Mar 2025 20:38:31 +0900 Subject: [PATCH 198/312] fix: test --- test/Limits.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Limits.t.sol b/test/Limits.t.sol index 1e4223c..e3e00c2 100644 --- a/test/Limits.t.sol +++ b/test/Limits.t.sol @@ -9,7 +9,7 @@ contract LimitsTest is EulerSwapTestBase { function setUp() public virtual override { super.setUp(); - eulerSwap = createEulerSwap(50e18, 50e18, 0, 1e18, 1e18, 0.9e18, 0.9e18); + eulerSwap = createEulerSwap(60e18, 60e18, 0, 1e18, 1e18, 0.9e18, 0.9e18); } function test_basicLimits() public { From 1c0720905b6e49fcaae8c2af5da04cd2bd671c3b Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 5 Mar 2025 21:07:18 +0900 Subject: [PATCH 199/312] add natspec --- src/EulerSwap.sol | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 792423f..dcf6b37 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -171,16 +171,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { IEVC(evc).enableCollateral(eulerAccount, vault1); } - function approveVault(address asset, address vault) internal { - address permit2 = IEVault(vault).permit2Address(); - if (permit2 == address(0)) { - IERC20(asset).forceApprove(vault, type(uint256).max); - } else { - IERC20(asset).forceApprove(permit2, type(uint256).max); - IAllowanceTransfer(permit2).approve(asset, vault, type(uint160).max, type(uint48).max); - } - } - /// @inheritdoc IEulerSwap function verify(uint256 newReserve0, uint256 newReserve1) public view returns (bool) { if (newReserve0 > type(uint112).max || newReserve1 > type(uint112).max) return false; @@ -231,6 +221,19 @@ contract EulerSwap is IEulerSwap, EVCUtil { return amount; } + /// @notice Approves tokens for a given vault, supporting both standard approvals and permit2 + /// @param asset The address of the token to approve + /// @param vault The address of the vault to approve the token for + function approveVault(address asset, address vault) internal { + address permit2 = IEVault(vault).permit2Address(); + if (permit2 == address(0)) { + IERC20(asset).forceApprove(vault, type(uint256).max); + } else { + IERC20(asset).forceApprove(permit2, type(uint256).max); + IAllowanceTransfer(permit2).approve(asset, vault, type(uint160).max, type(uint48).max); + } + } + function myDebt(address vault) internal view returns (uint256) { return IEVault(vault).debtOf(eulerAccount); } From 84d693989fefb46d572155499c4308f5a62aa226 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 5 Mar 2025 09:02:01 -0500 Subject: [PATCH 200/312] small clean-up and extra validation (chainsecurity finding 5.7) --- src/EulerSwapPeriphery.sol | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index f6ec589..e37a268 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -198,14 +198,15 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { unchecked { int256 reserve0New = int256(uint256(reserve0)) + dx; int256 reserve1New = int256(uint256(reserve1)) + dy; + require(reserve0New > 0 && reserve1New > 0, SwapLimitExceeded()); uint256 low; uint256 high = type(uint112).max; while (low < high) { uint256 mid = (low + high) / 2; + require(mid > 0, SwapLimitExceeded()); (uint256 a, uint256 b) = dy == 0 ? (uint256(reserve0New), mid) : (mid, uint256(reserve1New)); - require(a > 0 && b > 0, SwapLimitExceeded()); if (eulerSwap.verify(a, b)) { high = mid; } else { @@ -213,6 +214,8 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { } } + require(high < type(uint112).max, SwapLimitExceeded()); // at least one point verified + if (dx != 0) dy = int256(low) - reserve1New; else dx = int256(low) - reserve0New; } From cb362eb439aacd1b182a2532bc56336d5f4c1a27 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 6 Mar 2025 00:55:33 +0900 Subject: [PATCH 201/312] clean --- src/EulerSwap.sol | 25 ++++++++++++++++-- src/EulerSwapPeriphery.sol | 35 -------------------------- src/interfaces/IEulerSwap.sol | 4 +++ src/interfaces/IEulerSwapPeriphery.sol | 24 ------------------ 4 files changed, 27 insertions(+), 61 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index a8ccb6c..de30f0a 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -152,12 +152,12 @@ contract EulerSwap is IEulerSwap, EVCUtil { } } + /// @inheritdoc IEulerSwap function getReserves() external view returns (uint112, uint112, uint32) { return (reserve0, reserve1, status); } - /// @notice Returns the address of the Ethereum Vault Connector (EVC) used by this contract. - /// @return The address of the EVC contract. + /// @inheritdoc IEulerSwap function EVC() external view override(EVCUtil, IEulerSwap) returns (address) { return address(evc); } @@ -189,6 +189,13 @@ contract EulerSwap is IEulerSwap, EVCUtil { } } + /// @notice Withdraws assets from a vault, first using available balance and then borrowing if needed + /// @param vault The address of the vault to withdraw from + /// @param amount The total amount of assets to withdraw + /// @param to The address that will receive the withdrawn assets + /// @dev This function first checks if there's an existing balance in the vault. + /// @dev If there is, it withdraws the minimum of the requested amount and available balance. + /// @dev If more assets are needed after withdrawal, it enables the controller and borrows the remaining amount. function withdrawAssets(address vault, uint256 amount, address to) internal { uint256 balance = myBalance(vault); @@ -204,6 +211,14 @@ contract EulerSwap is IEulerSwap, EVCUtil { } } + /// @notice Deposits assets into a vault and automatically repays any outstanding debt + /// @param vault The address of the vault to deposit into + /// @param amount The amount of assets to deposit + /// @return The amount of assets successfully deposited + /// @dev This function attempts to deposit assets into the specified vault. + /// @dev If the deposit fails with E_ZeroShares error, it safely returns 0 (this happens with very small amounts). + /// @dev After successful deposit, if the user has any outstanding controller-enabled debt, it attempts to repay it. + /// @dev If all debt is repaid, the controller is automatically disabled to reduce gas costs in future operations. function depositAssets(address vault, uint256 amount) internal returns (uint256) { try IEVault(vault).deposit(amount, eulerAccount) {} catch (bytes memory reason) { @@ -237,10 +252,16 @@ contract EulerSwap is IEulerSwap, EVCUtil { } } + /// @notice Retrieves the current debt amount for the pool's eulerAccount + /// @param vault The address of the vault to check for debt + /// @return The amount of debt that the Euler account has in the specified vault function myDebt(address vault) internal view returns (uint256) { return IEVault(vault).debtOf(eulerAccount); } + /// @notice Calculates the asset balance of the pool's eulerAccount + /// @param vault The address of the vault to check for balance + /// @return The amount of assets that the Euler account has deposited in the specified vault function myBalance(address vault) internal view returns (uint256) { uint256 shares = IEVault(vault).balanceOf(eulerAccount); return shares == 0 ? 0 : IEVault(vault).convertToAssets(shares); diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index f6ec589..342630e 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -67,41 +67,6 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { return calcLimits(IEulerSwap(eulerSwap), checkTokens(IEulerSwap(eulerSwap), tokenIn, tokenOut)); } - /// @inheritdoc IEulerSwapPeriphery - function fInverse(uint256 y, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) - external - pure - returns (uint256) - { - // A component of the quadratic formula: a = 2 * c - uint256 A = 2 * c; - - // B component of the quadratic formula - int256 B = int256((px * (y - y0) + py - 1) / py) - int256((x0 * (2 * c - 1e18) + 1e18 - 1) / 1e18); - - // B^2 component, using FullMath for overflow safety - uint256 absB = B < 0 ? uint256(-B) : uint256(B); - uint256 squaredB = Math.mulDiv(absB, absB, 1e18, Math.Rounding.Ceil); - - // 4 * A * C component of the quadratic formula - uint256 AC4 = Math.mulDiv( - Math.mulDiv(4 * c, (1e18 - c), 1e18, Math.Rounding.Ceil), - Math.mulDiv(x0, x0, 1e18, Math.Rounding.Ceil), - 1e18, - Math.Rounding.Ceil - ); - - // Discriminant: b^2 + 4ac, scaled up to maintain precision - uint256 discriminant = (squaredB + AC4) * 1e18; - - // Square root of the discriminant (rounded up) - uint256 sqrt = Math.sqrt(discriminant); - sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; - - // Compute and return x = fInverse(y) using the quadratic formula - return Math.mulDiv(uint256(int256(sqrt) - B), 1e18, A, Math.Rounding.Ceil); - } - /// @dev Internal function to execute a token swap through EulerSwap /// @param eulerSwap The EulerSwap contract address to execute the swap through /// @param tokenIn The address of the input token being swapped diff --git a/src/interfaces/IEulerSwap.sol b/src/interfaces/IEulerSwap.sol index 535ba03..dd192ec 100644 --- a/src/interfaces/IEulerSwap.sol +++ b/src/interfaces/IEulerSwap.sol @@ -51,6 +51,10 @@ interface IEulerSwap { function equilibriumReserve0() external view returns (uint112); function equilibriumReserve1() external view returns (uint112); function feeMultiplier() external view returns (uint256); + /// @notice Returns the current reserves of the pool + /// @return reserve0 The amount of asset0 in the pool + /// @return reserve1 The amount of asset1 in the pool + /// @return status The status of the pool (0 = unactivated, 1 = unlocked, 2 = locked) function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 status); // Curve Accessors diff --git a/src/interfaces/IEulerSwapPeriphery.sol b/src/interfaces/IEulerSwapPeriphery.sol index 72cd76f..cb84b16 100644 --- a/src/interfaces/IEulerSwapPeriphery.sol +++ b/src/interfaces/IEulerSwapPeriphery.sol @@ -24,28 +24,4 @@ interface IEulerSwapPeriphery { /// @notice Max amount the pool can buy of tokenIn and sell of tokenOut function getLimits(address eulerSwap, address tokenIn, address tokenOut) external view returns (uint256, uint256); - - /** - * @notice Computes the inverse of the `f()` function for the EulerSwap liquidity curve. - * @dev Solves for `x` given `y` using the quadratic formula derived from the liquidity curve: - * x = (-b + sqrt(b^2 + 4ac)) / 2a - * Utilises mulDiv to avoid overflow and ensures precision with upward rounding. - * - * @param y The y-coordinate input value (must be greater than `y0`). - * @param px Price factor for the x-axis (scaled by 1e18, between 1e18 and 1e36). - * @param py Price factor for the y-axis (scaled by 1e18, between 1e18 and 1e36). - * @param x0 Reference x-value on the liquidity curve (≤ 2^112 - 1). - * @param y0 Reference y-value on the liquidity curve (≤ 2^112 - 1). - * @param c Curve parameter shaping liquidity concentration (scaled by 1e18, between 0 and 1e18). - * - * @return x The computed x-coordinate on the liquidity curve. - * - * @custom:precision Uses rounding up to maintain precision in all calculations. - * @custom:safety FullMath handles potential overflow in the b^2 computation. - * @custom:requirement Input `y` must be strictly greater than `y0`; otherwise, the function will revert. - */ - function fInverse(uint256 y, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) - external - pure - returns (uint256); } From c2d071ece60379da3a9f921979e2784815f85ac1 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 6 Mar 2025 01:02:53 +0900 Subject: [PATCH 202/312] remove test --- test/EulerSwapPeriphery.t.sol | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/test/EulerSwapPeriphery.t.sol b/test/EulerSwapPeriphery.t.sol index 036bc05..cf5398d 100644 --- a/test/EulerSwapPeriphery.t.sol +++ b/test/EulerSwapPeriphery.t.sol @@ -77,17 +77,4 @@ contract EulerSwapPeripheryTest is EulerSwapTestBase { periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut * 2, amountIn); vm.stopPrank(); } - - function test_fInverseFuzz(uint256 x) public view { - x = bound(x, 2, 50e18 - 1); // note that it fails if 1 used as minimum, not an issue since only used in periphery - uint256 y = eulerSwapHarness.exposedF(x, 1e18, 1e18, 50e18, 50e18, 0.85e18); - uint256 outX = periphery.fInverse(y, 1e18, 1e18, 50e18, 50e18, 0.85e18); - - // Ensure x is within the expected range - assertGe(outX, x); // Asserts xOut >= x - assertLe(outX, x + 1); // Asserts xOut <= x + 1 - - // Alternative using assertApproxEqAbs for absolute difference within 1 - assertApproxEqAbs(x, outX, 1); - } } From 54c1af6d7891583ddc0df332002bcbc6e06bb4cd Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 5 Mar 2025 15:45:52 -0500 Subject: [PATCH 203/312] correct quoting for exact output swaps when point is above curve (chainsecurity finding 5.4.3) --- src/EulerSwapPeriphery.sol | 4 ++-- test/Limits.t.sol | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index f0cba92..0c2bd74 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -189,8 +189,8 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { if (asset0IsInput) output = uint256(-dy); else output = uint256(-dx); } else { - if (asset0IsInput) output = uint256(dx); - else output = uint256(dy); + if (asset0IsInput) output = dx >= 0 ? uint256(dx) : 0; + else output = dy >= 0 ? uint256(dy) : 0; } } diff --git a/test/Limits.t.sol b/test/Limits.t.sol index e3e00c2..6e7e6d9 100644 --- a/test/Limits.t.sol +++ b/test/Limits.t.sol @@ -115,4 +115,35 @@ contract LimitsTest is EulerSwapTestBase { vm.expectRevert(EulerSwap.AmountTooBig.selector); eulerSwap.swap(0, type(uint256).max, address(this), ""); } + + function test_quoteWhenAboveCurve() public { + // Donate 100 and 100 to the pool, raising the reserves above the curve + assetTST.mint(depositor, 100e18); + assetTST2.mint(depositor, 100e18); + vm.prank(depositor); + assetTST.transfer(address(eulerSwap), 10e18); + vm.prank(depositor); + assetTST2.transfer(address(eulerSwap), 10e18); + eulerSwap.swap(0, 0, address(this), ""); + + uint256 amount; + + // Exact output quotes: Costs nothing to perform this swap (in theory the quote could + // be negative, but this is not supported by the interface) + + amount = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), 1e18); + assertEq(amount, 0); + + amount = periphery.quoteExactOutput(address(eulerSwap), address(assetTST2), address(assetTST), 1e18); + assertEq(amount, 0); + + // Exact input quotes: The additional extractable value is provided as swap output, even + // with tiny quotes such as 1 wei. + + amount = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), 1); + assertApproxEqAbs(amount, 19.8e18, 0.1e18); + + amount = periphery.quoteExactInput(address(eulerSwap), address(assetTST2), address(assetTST), 1); + assertApproxEqAbs(amount, 19.8e18, 0.1e18); + } } From 87d5da058d93b5a676127c61463789a0ab598164 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 5 Mar 2025 22:31:55 -0500 Subject: [PATCH 204/312] forge install: v4-periphery --- .gitmodules | 3 +++ lib/v4-periphery | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/v4-periphery diff --git a/.gitmodules b/.gitmodules index 7e69f48..86c64a9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "lib/ethereum-vault-connector"] path = lib/ethereum-vault-connector url = https://github.com/euler-xyz/ethereum-vault-connector +[submodule "lib/v4-periphery"] + path = lib/v4-periphery + url = https://github.com/uniswap/v4-periphery diff --git a/lib/v4-periphery b/lib/v4-periphery new file mode 160000 index 0000000..9628c36 --- /dev/null +++ b/lib/v4-periphery @@ -0,0 +1 @@ +Subproject commit 9628c36b4f5083d19606e63224e4041fe748edae From bf95e49b88f778d7add79e209a3ebbbcb861821f Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 5 Mar 2025 22:58:22 -0500 Subject: [PATCH 205/312] building --- remappings.txt | 1 + src/EulerSwap.sol | 1 + src/EulerSwapFactory.sol | 13 +++++++---- src/EulerSwapHook.sol | 40 +++++++++++++++++++++++++++++++++ test/EulerSwapFactoryTest.t.sol | 3 ++- 5 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 src/EulerSwapHook.sol diff --git a/remappings.txt b/remappings.txt index d217abb..8773f81 100644 --- a/remappings.txt +++ b/remappings.txt @@ -4,3 +4,4 @@ evk/=lib/euler-vault-kit/src/ ethereum-vault-connector/=lib/ethereum-vault-connector/src/ evk-test/=lib/euler-vault-kit/test/ permit2/=lib/euler-vault-kit/lib/permit2/ +@uniswap/v4-core/=lib/v4-periphery/lib/v4-core/ \ No newline at end of file diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index a9e3695..a71e97c 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -102,6 +102,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { /// @inheritdoc IEulerSwap function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external + virtual callThroughEVC nonReentrant { diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 28ae63d..c8826ce 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -1,8 +1,9 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; +import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {IEulerSwapFactory, IEulerSwap} from "./interfaces/IEulerSwapFactory.sol"; -import {EulerSwap} from "./EulerSwap.sol"; +import {EulerSwapHook} from "./EulerSwapHook.sol"; import {EVCUtil} from "ethereum-vault-connector/utils/EVCUtil.sol"; /// @title EulerSwapFactory contract @@ -14,6 +15,8 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { /// @dev Mapping between euler account and deployed pool that is currently set as operator mapping(address eulerAccount => address operator) public eulerAccountToPool; + IPoolManager immutable poolManager; + event PoolDeployed( address indexed asset0, address indexed asset1, @@ -33,7 +36,9 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { error OldOperatorStillInstalled(); error OperatorNotInstalled(); - constructor(address evc) EVCUtil(evc) {} + constructor(IPoolManager _manager, address evc) EVCUtil(evc) { + poolManager = _manager; + } /// @notice Deploy a new EulerSwap pool with the given parameters /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from @@ -49,13 +54,13 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { { require(_msgSender() == params.eulerAccount, Unauthorized()); - EulerSwap pool = new EulerSwap{salt: keccak256(abi.encode(params.eulerAccount, salt))}(params, curveParams); + EulerSwapHook pool = new EulerSwapHook{salt: keccak256(abi.encode(params.eulerAccount, salt))}(poolManager, params, curveParams); checkEulerAccountOperators(params.eulerAccount, address(pool)); allPools.push(address(pool)); - EulerSwap(pool).activate(); + pool.activate(); emit PoolDeployed( pool.asset0(), diff --git a/src/EulerSwapHook.sol b/src/EulerSwapHook.sol new file mode 100644 index 0000000..3c24db3 --- /dev/null +++ b/src/EulerSwapHook.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.27; + +import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; +import {BaseHook} from "v4-periphery/src/utils/BaseHook.sol"; +import {PoolKey} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; +import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; +import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; +import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; +import {EulerSwap, IEulerSwap, IEVault} from "./EulerSwap.sol"; + +contract EulerSwapHook is EulerSwap, BaseHook { + PoolKey poolKey; + + constructor(IPoolManager _manager, Params memory params, CurveParams memory curveParams) + EulerSwap(params, curveParams) + BaseHook(_manager) + { + address asset0Addr = IEVault(params.vault0).asset(); + address asset1Addr = IEVault(params.vault1).asset(); + + // convert fee in WAD to pips. 0.003e18 / 1e12 = 3000 = 0.30% + uint24 fee = uint24(params.fee / 1e12); + + poolKey = PoolKey({ + currency0: Currency.wrap(asset0Addr), + currency1: Currency.wrap(asset1Addr), + fee: fee, + tickSpacing: 60, // TODO: fix arbitrary tick spacing + hooks: IHooks(address(this)) + }); + + // create the pool on v4, using starting price as sqrtPrice(1/1) * Q96 + poolManager.initialize(poolKey, 79228162514264337593543950336); + } + + // TODO: fix salt mining & verification for the hook + function getHookPermissions() public pure override returns (Hooks.Permissions memory) {} + function validateHookAddress(BaseHook) internal pure override {} +} diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index b7fa719..d7a68ba 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.24; +import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {EulerSwapTestBase, IEulerSwap, IEVC, EulerSwap} from "./EulerSwapTestBase.t.sol"; import {EulerSwapFactory, IEulerSwapFactory} from "../src/EulerSwapFactory.sol"; @@ -13,7 +14,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { super.setUp(); vm.prank(creator); - eulerSwapFactory = new EulerSwapFactory(address(evc)); + eulerSwapFactory = new EulerSwapFactory(IPoolManager(address(0)), address(evc)); } function testDeployPool() public { From 6b987bf4be96f9494b9012f6d3a2602c435c6e0d Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 5 Mar 2025 23:02:49 -0500 Subject: [PATCH 206/312] forge fmt --- src/EulerSwapFactory.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index c8826ce..a97adfc 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -54,7 +54,8 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { { require(_msgSender() == params.eulerAccount, Unauthorized()); - EulerSwapHook pool = new EulerSwapHook{salt: keccak256(abi.encode(params.eulerAccount, salt))}(poolManager, params, curveParams); + EulerSwapHook pool = + new EulerSwapHook{salt: keccak256(abi.encode(params.eulerAccount, salt))}(poolManager, params, curveParams); checkEulerAccountOperators(params.eulerAccount, address(pool)); From 578f2f9589f4dc6822cc416f8ddf92ae79c4ae14 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 5 Mar 2025 23:55:31 -0500 Subject: [PATCH 207/312] fix test; added utilities for tests --- src/utils/HookMiner.sol | 70 ++++++++++++++++++++++++++++++ test/EulerSwapFactoryTest.t.sol | 32 +++++++++++--- test/utils/PoolManagerDeployer.sol | 27 ++++++++++++ 3 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 src/utils/HookMiner.sol create mode 100644 test/utils/PoolManagerDeployer.sol diff --git a/src/utils/HookMiner.sol b/src/utils/HookMiner.sol new file mode 100644 index 0000000..5b98dbe --- /dev/null +++ b/src/utils/HookMiner.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.21; + +import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; + +/// @title HookMiner +/// @notice a minimal library for mining hook addresses +library HookMiner { + // mask to slice out the bottom 14 bit of the address + uint160 constant FLAG_MASK = Hooks.ALL_HOOK_MASK; // 0000 ... 0000 0011 1111 1111 1111 + + // Maximum number of iterations to find a salt, avoid infinite loops or MemoryOOG + // (arbitrarily set) + uint256 constant MAX_LOOP = 160_444; + + /// @notice Find a salt that produces a hook address with the desired `flags` + /// @param deployer The address that will deploy the hook. In `forge test`, this will be the test contract `address(this)` or the pranking address + /// In `forge script`, this should be `0x4e59b44847b379578588920cA78FbF26c0B4956C` (CREATE2 Deployer Proxy) + /// @param flags The desired flags for the hook address. Example `uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.AFTER_SWAP_FLAG | ...)` + /// @param creationCode The creation code of a hook contract. Example: `type(Counter).creationCode` + /// @param constructorArgs The encoded constructor arguments of a hook contract. Example: `abi.encode(address(manager))` + /// @return (hookAddress, salt) The hook deploys to `hookAddress` when using `salt` with the syntax: `new Hook{salt: salt}()` + function find( + address deployer, + address account, + uint160 flags, + bytes memory creationCode, + bytes memory constructorArgs + ) internal view returns (address, bytes32) { + flags = flags & FLAG_MASK; // mask for only the bottom 14 bits + bytes memory creationCodeWithArgs = abi.encodePacked(creationCode, constructorArgs); + + address hookAddress; + for (uint256 salt; salt < MAX_LOOP; salt++) { + hookAddress = computeAddress(deployer, account, salt, creationCodeWithArgs); + + // if the hook's bottom 14 bits match the desired flags AND the address does not have bytecode, we found a match + if (uint160(hookAddress) & FLAG_MASK == flags && hookAddress.code.length == 0) { + return (hookAddress, bytes32(salt)); + } + } + revert("HookMiner: could not find salt"); + } + + /// @notice Precompute a contract address deployed via CREATE2 + /// @param deployer The address that will deploy the hook. In `forge test`, this will be the test contract `address(this)` or the pranking address + /// In `forge script`, this should be `0x4e59b44847b379578588920cA78FbF26c0B4956C` (CREATE2 Deployer Proxy) + /// @param salt The salt used to deploy the hook + /// @param creationCodeWithArgs The creation code of a hook contract, with encoded constructor arguments appended. Example: `abi.encodePacked(type(Counter).creationCode, abi.encode(constructorArg1, constructorArg2))` + function computeAddress(address deployer, address account, uint256 salt, bytes memory creationCodeWithArgs) + internal + pure + returns (address hookAddress) + { + return address( + uint160( + uint256( + keccak256( + abi.encodePacked( + bytes1(0xFF), + deployer, + keccak256(abi.encode(account, salt)), + keccak256(creationCodeWithArgs) + ) + ) + ) + ) + ); + } +} diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index d7a68ba..f6ce268 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -2,29 +2,41 @@ pragma solidity ^0.8.24; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; +import {PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol"; +import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; +import {HookMiner} from "../src/utils/HookMiner.sol"; import {EulerSwapTestBase, IEulerSwap, IEVC, EulerSwap} from "./EulerSwapTestBase.t.sol"; import {EulerSwapFactory, IEulerSwapFactory} from "../src/EulerSwapFactory.sol"; +import {EulerSwapHook} from "../src/EulerSwapHook.sol"; contract EulerSwapFactoryTest is EulerSwapTestBase { EulerSwapFactory public eulerSwapFactory; + IPoolManager public poolManager; uint256 minFee = 0.0000000000001e18; function setUp() public virtual override { super.setUp(); - vm.prank(creator); - eulerSwapFactory = new EulerSwapFactory(IPoolManager(address(0)), address(evc)); + vm.startPrank(creator); + poolManager = PoolManagerDeployer.deploy(creator); + eulerSwapFactory = new EulerSwapFactory(poolManager, address(evc)); + vm.stopPrank(); } function testDeployPool() public { uint256 allPoolsLengthBefore = eulerSwapFactory.allPoolsLength(); - bytes32 salt = bytes32(uint256(1234)); IEulerSwap.Params memory poolParams = IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 0); IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); + uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG); + bytes memory constructorArgs = abi.encode(poolManager, poolParams, curveParams); + (address hookAddress, bytes32 salt) = + HookMiner.find(address(eulerSwapFactory), holder, flags, type(EulerSwapHook).creationCode, constructorArgs); + address predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); + assertEq(hookAddress, predictedAddress); IEVC.BatchItem[] memory items = new IEVC.BatchItem[](2); @@ -54,12 +66,18 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { assertEq(poolsList[0], address(eulerSwap)); assertEq(eulerSwapFactory.allPools(0), address(eulerSwap)); + // revert when attempting to deploy a new pool (with a different salt) + (address newHookAddress, bytes32 newSalt) = + HookMiner.find(address(eulerSwapFactory), holder, flags, type(EulerSwapHook).creationCode, constructorArgs); + assertNotEq(newHookAddress, hookAddress); + assertNotEq(newSalt, salt); + items = new IEVC.BatchItem[](1); items[0] = IEVC.BatchItem({ onBehalfOfAccount: holder, targetContract: address(eulerSwapFactory), value: 0, - data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, bytes32(uint256(12345)))) + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, newSalt)) }); vm.prank(holder); @@ -97,7 +115,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { IEulerSwap.Params memory poolParams, IEulerSwap.CurveParams memory curveParams, bytes32 salt - ) internal pure returns (address) { + ) internal view returns (address) { return address( uint160( uint256( @@ -107,7 +125,9 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { factoryAddress, keccak256(abi.encode(address(poolParams.eulerAccount), salt)), keccak256( - abi.encodePacked(type(EulerSwap).creationCode, abi.encode(poolParams, curveParams)) + abi.encodePacked( + type(EulerSwapHook).creationCode, abi.encode(poolManager, poolParams, curveParams) + ) ) ) ) diff --git a/test/utils/PoolManagerDeployer.sol b/test/utils/PoolManagerDeployer.sol new file mode 100644 index 0000000..04b53ad --- /dev/null +++ b/test/utils/PoolManagerDeployer.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity >= 0.8.0; + +import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; + +// temporarily stolen from: https://github.com/Uniswap/briefcase/blob/main/src/deployers/v4-core/PoolManagerDeployer.sol +library PoolManagerDeployer { + function deploy(address initialOwner) internal returns (IPoolManager manager) { + bytes memory args = abi.encode(initialOwner); + bytes memory initcode_ = abi.encodePacked(initcode(), args); + + assembly { + manager := create2(0, add(initcode_, 32), mload(initcode_), hex"00") + } + } + + /** + * @dev autogenerated - run `./script/util/create_briefcase.sh` to generate current initcode + * + * @notice This initcode is generated from the following contract: + * - Source Contract: lib/v4-core/src/PoolManager.sol + */ + function initcode() internal pure returns (bytes memory) { + return + hex"60a03460a057601f615e8238819003918201601f19168301916001600160401b0383118484101760a45780849260209460405283398101031260a057516001600160a01b0381169081900360a0575f80546001600160a01b0319168217815560405191907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a330608052615dc990816100b98239608051816135260152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe60a0806040526004361015610012575f80fd5b5f3560e01c908162fdd58e14612cd55750806301ffc9a714612c16578063095bcdb614612b6c5780630b0d9c0914612ae057806311da60b414612a85578063156e29f6146129d55780631e2eaeaf1461299b578063234266d7146126fc5780632d7713891461265157806335fd631a146125dd5780633dd45adb14612579578063426a8493146124f557806348c894911461226a5780635275965114612152578063558a72971461207b578063598af9e714611fe35780635a6bcfda1461144f5780636276cbbe14610f965780637e87ce7d14610e5957806380f0b44c14610d875780638161b87414610c315780638da5cb5b14610be157806397e8cd4e14610b7e5780639bf6645f14610b31578063a584119414610a66578063b6363cf2146109d5578063dbd035ff1461097f578063f02de3b21461092e578063f135baaa146108f4578063f2fde38b14610848578063f3cd914c146104ff578063f5298aca146103345763fe99049a14610186575f80fd5b346103305760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330576101bd612d3f565b6101c5612d62565b90604435917f1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac72885961027973ffffffffffffffffffffffffffffffffffffffff80606435951693843314158061030d575b610287575b845f52600460205260405f20875f5260205260405f2061023a878254612fed565b90551693845f52600460205260405f20865f5260205260405f2061025f828254612ffa565b905560408051338152602081019290925290918291820190565b0390a4602060405160018152f35b845f52600560205260405f208233165f5260205260405f20875f5260205260405f2054867fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036102da575b5050610219565b6102e391612fed565b855f52600560205260405f208333165f5260205260405f20885f5260205260405f20555f866102d3565b50845f52600360205260405f208233165f5260205260ff60405f20541615610214565b5f80fd5b346103305761034236612d85565b7fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d7577f1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac7288596103ed73ffffffffffffffffffffffffffffffffffffffff805f9516956103bb6103b3866130aa565b3390896130f0565b169233841415806104a0575b6103f2575b8385526004602052604085208686526020526040852061025f828254612fed565b0390a4005b83855260056020526040852073ffffffffffffffffffffffffffffffffffffffff33168652602052604085208686526020526040852054817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610459575b50506103cc565b61046291612fed565b84865260056020526040862073ffffffffffffffffffffffffffffffffffffffff331687526020526040862087875260205260408620558681610452565b5083855260036020526040852073ffffffffffffffffffffffffffffffffffffffff3316865260205260ff604086205416156103c7565b7f54e3ca0d000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610330576101207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305761053836612e81565b60607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c360112610330576040519061056f82612df6565b60a4358015158103610330578252602082019060c435825260e4359073ffffffffffffffffffffffffffffffffffffffff8216820361033057604084019182526101043567ffffffffffffffff8111610330576105d0903690600401612f4d565b9290937fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d75761060261350f565b51156108205760a0822092835f52600660205260405f209061062382613576565b60808401958482828a8a5173ffffffffffffffffffffffffffffffffffffffff169361064e94613b44565b90949195606088015160020b908b511515905173ffffffffffffffffffffffffffffffffffffffff1691604051986106858a612e12565b895260208901526040880152606087015262ffffff166080860152885115155f149862ffffff6107a2986106db61078f9860209d6108005773ffffffffffffffffffffffffffffffffffffffff8b511695614959565b9492968291926107d3575b505073ffffffffffffffffffffffffffffffffffffffff845116938e6fffffffffffffffffffffffffffffffff60408301511691015160020b90604051958860801d600f0b875288600f0b60208801526040870152606086015260808501521660a08301527f40e9cecb9f5f1f1c5b9c97dec2917b7ee92e57ba5563708daca94dd84ad7112f60c03393a38673ffffffffffffffffffffffffffffffffffffffff8a5116613d81565b809491946107aa575b5050823391613652565b604051908152f35b73ffffffffffffffffffffffffffffffffffffffff6107cc9251169083613652565b8480610798565b73ffffffffffffffffffffffffffffffffffffffff165f5260018f5260405f209081540190558e806106e6565b73ffffffffffffffffffffffffffffffffffffffff8e8c01511695614959565b7fbe8b8507000000000000000000000000000000000000000000000000000000005f5260045ffd5b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330577fffffffffffffffffffffffff00000000000000000000000000000000000000006108a0612d3f565b73ffffffffffffffffffffffffffffffffffffffff5f54916108c58284163314613007565b1691829116175f55337f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330576004355c5f5260205ff35b34610330575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057602073ffffffffffffffffffffffffffffffffffffffff60025416604051908152f35b346103305761098d36612f7b565b6040519160408360208152836020820152019160051b8301916020806040850193925b83355481520191019084838210156109cc5750602080916109b0565b60408186030190f35b346103305760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057610a0c612d3f565b73ffffffffffffffffffffffffffffffffffffffff610a29612d62565b91165f52600360205273ffffffffffffffffffffffffffffffffffffffff60405f2091165f52602052602060ff60405f2054166040519015158152f35b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057610a9d612d3f565b73ffffffffffffffffffffffffffffffffffffffff81169081610ae15750505f7f27e098c505d44ec3574004bca052aabf76bd35004c182099d8c575fb238593b95d005b610aea90613a92565b907f27e098c505d44ec3574004bca052aabf76bd35004c182099d8c575fb238593b95d7f1e0745a7db1623981f0b2a5d4232364c00787266eb75ad546f190e6cebe9bd955d005b3461033057610b3f36612f7b565b6040519160408360208152836020820152019160051b8301916020806040850193925b83355c81520191019084838210156109cc575060208091610b62565b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305773ffffffffffffffffffffffffffffffffffffffff610bca612d3f565b165f526001602052602060405f2054604051908152f35b34610330575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057602073ffffffffffffffffffffffffffffffffffffffff5f5416604051908152f35b346103305760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057610c68612d3f565b610c70612d62565b60443573ffffffffffffffffffffffffffffffffffffffff600254163303610d5f5773ffffffffffffffffffffffffffffffffffffffff821680151580610d1f575b610cf7576020936107a29280610cef5750815f526001855260405f20549384925b5f526001865260405f20610ce8848254612fed565b90556131f8565b938492610cd3565b7fc79e5948000000000000000000000000000000000000000000000000000000005f5260045ffd5b508073ffffffffffffffffffffffffffffffffffffffff7f27e098c505d44ec3574004bca052aabf76bd35004c182099d8c575fb238593b95c1614610cb2565b7f48f5c3ed000000000000000000000000000000000000000000000000000000005f5260045ffd5b346103305760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057610dbe612d3f565b7fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d757335f90815273ffffffffffffffffffffffffffffffffffffffff8216602052604090205c610e146024356130aa565b9081600f0b03610e3157610e2f9133915f03600f0b906130f0565b005b7fbda73abf000000000000000000000000000000000000000000000000000000005f5260045ffd5b346103305760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057610e9136612e81565b610e99612e6f565b9073ffffffffffffffffffffffffffffffffffffffff600254163303610d5f57623e900062fff0008316106103e9610fff8416101615610f6557602060a07fe9c42593e71f84403b84352cd168d693e2c9fcd1fdbcc3feb21d92b43e6696f9922092835f526006825260405f20610f0f81613576565b805479ffffff00000000000000000000000000000000000000000000008360b81b16907fffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffff1617905562ffffff60405191168152a2005b62ffffff827fa7abe2f7000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b346103305760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057610fce36612e81565b60a4359073ffffffffffffffffffffffffffffffffffffffff821680830361033057610ff861350f565b6060820191825160020b617fff81136114245750825160020b600181126113f9575073ffffffffffffffffffffffffffffffffffffffff815116602082019073ffffffffffffffffffffffffffffffffffffffff825116808210156113c2575050608082019073ffffffffffffffffffffffffffffffffffffffff82511690604084019161108c62ffffff845116826139b7565b1561139757506110a162ffffff835116613a75565b96835173ffffffffffffffffffffffffffffffffffffffff8116908133036112e0575b505060a0852090815f52600660205260405f2090815473ffffffffffffffffffffffffffffffffffffffff166112b8576020997fdd466e674ea557f56295e2d0218a125ea4b4f0f6f3307b95f85e6110838d6438927cffffff000000000000000000000000000000000000000000000000000061114260a0946145fc565b9260d01b168a76ffffff000000000000000000000000000000000000000084861b161717905562ffffff73ffffffffffffffffffffffffffffffffffffffff808a5116965116965116995160020b73ffffffffffffffffffffffffffffffffffffffff885116906040519b8c528c8c015260408b01528860608b015260020b98896080820152a45173ffffffffffffffffffffffffffffffffffffffff8116908133036111f4575b8585604051908152f35b61100016611203575b806111ea565b6112af9261128d604051937f6fe7e6eb0000000000000000000000000000000000000000000000000000000088860152336024860152604485019073ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b60e48301528361010483015261010482526112aa61012483612e2e565b613f25565b508280806111fd565b7f7983c051000000000000000000000000000000000000000000000000000000005f5260045ffd5b612000166112ef575b806110c4565b61139090604051907fdc98354e00000000000000000000000000000000000000000000000000000000602083015233602483015261137a604483018973ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b8860e483015260e482526112aa61010483612e2e565b50886112e9565b7fe65af6a0000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b60449250604051917f6e6c983000000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b7fe9e90588000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b7fb70024f8000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b34610330576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305761148836612e81565b60807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c36011261033057604051906114bf82612dda565b60a4358060020b810361033057825260c4358060020b810361033057602083015260e43560408301526101043560608301526101243567ffffffffffffffff811161033057611512903690600401612f4d565b90927fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d75761154361350f565b60a0832093845f52600660205260405f20608052611562608051613576565b608084015173ffffffffffffffffffffffffffffffffffffffff811690813303611ede575b5050815160020b92602083015160020b916115a56040850151613785565b93606087015160020b9760608201516040519960c08b018b811067ffffffffffffffff821117611eb157604052338b528860208c01528660408c015287600f0b60608c015260808b015260a08a01525f9185881215611e7a577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276188812611e4e57620d89e88613611e22576040519261163c84612dda565b5f84525f60208501525f60408501525f606085015287600f0b611b25575b600460805101978960020b5f528860205260405f20988860020b5f5260205260405f206080515460a01c60020b8b81125f14611acf575060028060018c0154600184015490039b015491015490039b5b60a073ffffffffffffffffffffffffffffffffffffffff825116910151906040519160268301528960068301528b600383015281525f603a600c83012091816040820152816020820152525f5260066080510160205260405f20976fffffffffffffffffffffffffffffffff8954169982600f0b155f14611a72578a15611a4a5761176f61176960409f9b61184e9c6118609e5b60018301956117616002611755848a548503615703565b95019283548503615703565b9655556130aa565b916130aa565b6fffffffffffffffffffffffffffffffff169060801b179a8b965f84600f0b126119dc575b5082600f0b611898575b5050506117c46117b58560801d8360801d01613785565b9185600f0b90600f0b01613785565b6fffffffffffffffffffffffffffffffff169060801b1791815160020b90602083015160020b8c8401516060850151918e5194855260208501528d84015260608301527ff208f4912782fd25c7f114ca3723a2d5dd6f3bcc3ac8db5af63baa85f711d5ec60803393a38873ffffffffffffffffffffffffffffffffffffffff60808201511661385b565b8094919461186c575b50833391613652565b82519182526020820152f35b6118929073ffffffffffffffffffffffffffffffffffffffff6080840151169083613652565b85611857565b60805154929350909173ffffffffffffffffffffffffffffffffffffffff81169060a01c60020b828112156118fe575050906118f2926118e76118dd6118ed94614158565b91600f0b92614158565b90614527565b613785565b60801b5b8b808061179e565b92809193125f146119a95761193d9161192a6118ed6118ed9361192488600f0b91614158565b87614527565b9361193886600f0b92614158565b6144ca565b6fffffffffffffffffffffffffffffffff169060801b17906fffffffffffffffffffffffffffffffff61197c60036080510192600f0b8284541661456e565b167fffffffffffffffffffffffffffffffff000000000000000000000000000000008254161790556118f6565b906118ed9250926119bf6118dd6119c595614158565b906144ca565b6fffffffffffffffffffffffffffffffff166118f6565b808f9151611a1e575b01516119f2575b8e611794565b611a198260805160049160020b5f52016020525f6002604082208281558260018201550155565b6119ec565b611a458360805160049160020b5f52016020525f6002604082208281558260018201550155565b6119e5565b7faefeb924000000000000000000000000000000000000000000000000000000005f5260045ffd5b61176f61176960409f9b61184e9c6118609e6fffffffffffffffffffffffffffffffff611aa289600f0b8361456e565b167fffffffffffffffffffffffffffffffff0000000000000000000000000000000084541617835561173e565b9099908913611af55760028060018c0154600184015490039b015491015490039b6116aa565b9860026001608051015460018c01549003600183015490039a81806080510154910154900391015490039b6116aa565b6004608051018960020b5f5280602052898960405f20611b7e81546fffffffffffffffffffffffffffffffff611b6181831695600f0b8661456e565b16931594858515141595611dee575b508d600f0b9060801d613d3a565b60801b82179055602087015285528760020b5f5260205260405f208054906fffffffffffffffffffffffffffffffff8216611bbc8b600f0b8261456e565b901592836fffffffffffffffffffffffffffffffff831615141593611dc1575b8b600f0b9060801d600f0b03916f7fffffffffffffffffffffffffffffff83137fffffffffffffffffffffffffffffffff80000000000000000000000000000000841217611d9457826fffffffffffffffffffffffffffffffff935060801b83831617905516606086015260408501525f88600f0b1215611ca1575b8351611c85575b60408401511561165a57611c8060808c015160020b8860056080510161410c565b61165a565b611c9c60808c015160020b8a60056080510161410c565b611c5f565b60808b015160020b6fffffffffffffffffffffffffffffffff600181602088015116925f817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276180712817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618050390620d89e8050301810416809111611d68576fffffffffffffffffffffffffffffffff6060860151161115611c5857867fb8e3c385000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b897fb8e3c385000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6080515460a01c60020b8b13611bdc57600160805101546001840155600260805101546002840155611bdc565b6080515460a01c60020b1215611e05575b8e611b70565b600160805101546001840155600260805101546002840155611dff565b857f1ad777f8000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b877fd5e2f7ab000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b60448887604051917fc4433ed500000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f604085015113808091611fd6575b15611f6b5750506040517f259982e5000000000000000000000000000000000000000000000000000000006020820152611f62916112aa82611f368887898c33602487016136cb565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101845283612e2e565b505b8580611587565b159081611fc8575b50611f7f575b50611f64565b6040517f21d0ee70000000000000000000000000000000000000000000000000000000006020820152611fc1916112aa82611f368887898c33602487016136cb565b5085611f79565b610200915016151587611f73565b5061080082161515611eed565b346103305760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305761201a612d3f565b73ffffffffffffffffffffffffffffffffffffffff612037612d62565b91165f52600560205273ffffffffffffffffffffffffffffffffffffffff60405f2091165f5260205260405f206044355f52602052602060405f2054604051908152f35b346103305760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330576120b2612d3f565b602435908115158092036103305773ffffffffffffffffffffffffffffffffffffffff90335f52600360205260405f208282165f5260205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541660ff851617905560405192835216907fceb576d9f15e4e200fdb5096d64d5dfd667e16def20c1eefd14256d8e3faa26760203392a3602060405160018152f35b346103305760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305761218a36612e81565b612192612e6f565b906280000062ffffff60408301511614801590612246575b61221e5760a0906121ba8361368e565b205f52600660205260405f20906121d082613576565b81547fffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffff1660d09190911b7cffffff000000000000000000000000000000000000000000000000000016179055005b7f30d21641000000000000000000000000000000000000000000000000000000005f5260045ffd5b5073ffffffffffffffffffffffffffffffffffffffff6080820151163314156121aa565b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305760043567ffffffffffffffff8111610330576122b9903690600401612f4d565b7fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c6124cd57612345915f9160017fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235d60405193849283927f91dd734600000000000000000000000000000000000000000000000000000000845260206004850152602484019161306c565b038183335af19081156124c2575f9161241a575b507f7d4b3164c6e45b97e7d87b7125a44c5828d005af88f9d751cfd78729c5d99a0b5c6123f25760406020915f7fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f835194859381855280519182918282880152018686015e5f85828601015201168101030190f35b7f5212cba1000000000000000000000000000000000000000000000000000000005f5260045ffd5b90503d805f833e61242b8183612e2e565b8101906020818303126103305780519067ffffffffffffffff8211610330570181601f820112156103305780519067ffffffffffffffff8211611eb1576040519261249e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8601160185612e2e565b8284526020838301011161033057815f9260208093018386015e8301015281612359565b6040513d5f823e3d90fd5b7f5090d6c6000000000000000000000000000000000000000000000000000000005f5260045ffd5b346103305773ffffffffffffffffffffffffffffffffffffffff61251836612d85565b91929092335f52600560205260405f208282165f5260205260405f20845f526020528260405f205560405192835216907fb3fd5071835887567a0671151121894ddccc2842f1d10bedad13e0d17cace9a760203392a4602060405160018152f35b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330576125ab612d3f565b7fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d7576107a260209161342d565b346103305760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330576024356004356040519160408360208152826020820152019060051b8301916001602060408501935b835481520191019084838210156109cc57506020600191612635565b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305773ffffffffffffffffffffffffffffffffffffffff61269d612d3f565b6126ab825f54163314613007565b16807fffffffffffffffffffffffff000000000000000000000000000000000000000060025416176002557fb4bd8ef53df690b9943d3318996006dbb82a25f54719d8c8035b516a2a5b8acc5f80a2005b34610330576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305761273536612e81565b60c4359060a43560e43567ffffffffffffffff81116103305761275c903690600401612f4d565b9190937fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d75761278e61350f565b60a0842094855f52600660205260405f20946127a986613576565b60808101805173ffffffffffffffffffffffffffffffffffffffff811690813303612943575b50506fffffffffffffffffffffffffffffffff60038801541697881561291b576020986127fb876130aa565b5f03612806876130aa565b5f036fffffffffffffffffffffffffffffffff169060801b179887612907575b866128f2575b5050612839338985613652565b60405190868252858a8301527f29ef05caaff9404b7cb6d1c0e9bbae9eaa7ab2541feba1a9c4248594c08156cb60403393a3519273ffffffffffffffffffffffffffffffffffffffff841693843303612897575b8888604051908152f35b6010166128a5575b8061288d565b6128e6956112aa93611f36926040519788957fe1b4af69000000000000000000000000000000000000000000000000000000008d88015233602488016135bc565b5082808080808061289f565b600201908660801b048154019055898061282c565b60018101828960801b048154019055612826565b7fa74f97ab000000000000000000000000000000000000000000000000000000005f5260045ffd5b602016612951575b806127cf565b6040517fb6a8b0fa000000000000000000000000000000000000000000000000000000006020820152612994916112aa82611f368b898b8d8b33602488016135bc565b508861294b565b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057600435545f5260205ff35b34610330576129e336612d85565b907fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d7577f1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac7288596103ed73ffffffffffffffffffffffffffffffffffffffff805f941695612a62612a55876130aa565b8603600f0b3390896130f0565b16938484526004602052604084208685526020526040842061025f828254612ffa565b5f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330577fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d75760206107a23361342d565b346103305760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057612b17612d3f565b612b1f612d62565b604435907fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d757610e2f92612b67612b5a846130aa565b5f03600f0b3390836130f0565b6131f8565b346103305773ffffffffffffffffffffffffffffffffffffffff612b8f36612d85565b91929092335f52600460205260405f20845f5260205260405f20612bb4848254612fed565b90551690815f52600460205260405f20835f5260205260405f20612bd9828254612ffa565b9055604080513380825260208201939093527f1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac7288599181908101610279565b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361033057807f01ffc9a70000000000000000000000000000000000000000000000000000000060209214908115612cab575b506040519015158152f35b7f0f632fb30000000000000000000000000000000000000000000000000000000091501482612ca0565b346103305760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305760209073ffffffffffffffffffffffffffffffffffffffff612d24612d3f565b165f526004825260405f206024355f52825260405f20548152f35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361033057565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361033057565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60609101126103305760043573ffffffffffffffffffffffffffffffffffffffff8116810361033057906024359060443590565b6080810190811067ffffffffffffffff821117611eb157604052565b6060810190811067ffffffffffffffff821117611eb157604052565b60a0810190811067ffffffffffffffff821117611eb157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117611eb157604052565b60a4359062ffffff8216820361033057565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60a09101126103305760405190612eb882612e12565b8160043573ffffffffffffffffffffffffffffffffffffffff8116810361033057815260243573ffffffffffffffffffffffffffffffffffffffff8116810361033057602082015260443562ffffff811681036103305760408201526064358060020b81036103305760608201526084359073ffffffffffffffffffffffffffffffffffffffff821682036103305760800152565b9181601f840112156103305782359167ffffffffffffffff8311610330576020838186019501011161033057565b9060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103305760043567ffffffffffffffff811161033057826023820112156103305780600401359267ffffffffffffffff84116103305760248460051b83010111610330576024019190565b91908203918211611d9457565b91908201809211611d9457565b1561300e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152fd5b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe093818652868601375f8582860101520116010190565b6f800000000000000000000000000000008110156130c857600f0b90565b7f93dafdf1000000000000000000000000000000000000000000000000000000005f5260045ffd5b9190600f0b9182156131f357613126919073ffffffffffffffffffffffffffffffffffffffff8092165f521660205260405f2090565b613132815c9283613b29565b80915d6131a357507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f7d4b3164c6e45b97e7d87b7125a44c5828d005af88f9d751cfd78729c5d99a0b5c017f7d4b3164c6e45b97e7d87b7125a44c5828d005af88f9d751cfd78729c5d99a0b5d5b565b156131aa57565b60017f7d4b3164c6e45b97e7d87b7125a44c5828d005af88f9d751cfd78729c5d99a0b5c017f7d4b3164c6e45b97e7d87b7125a44c5828d005af88f9d751cfd78729c5d99a0b5d565b505050565b90919073ffffffffffffffffffffffffffffffffffffffff811690816132ea5750505f80808093855af11561322a5750565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f3d011673ffffffffffffffffffffffffffffffffffffffff604051927f90bfb8650000000000000000000000000000000000000000000000000000000084521660048301525f6024830152608060448301528060a00160648301523d60848301523d5f60a484013e7ff4b3b1bc0000000000000000000000000000000000000000000000000000000060c4828401600460a4820152015260e40190fd5b60205f60448194968260409573ffffffffffffffffffffffffffffffffffffffff988751998a947fa9059cbb00000000000000000000000000000000000000000000000000000000865216600485015260248401525af13d15601f3d116001855114161716928281528260208201520152156133635750565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f3d0116604051917f90bfb86500000000000000000000000000000000000000000000000000000000835260048301527fa9059cbb000000000000000000000000000000000000000000000000000000006024830152608060448301528060a00160648301523d60848301523d5f60a484013e7ff27f64e40000000000000000000000000000000000000000000000000000000060c4828401600460a4820152015260e40190fd5b7f27e098c505d44ec3574004bca052aabf76bd35004c182099d8c575fb238593b95c919073ffffffffffffffffffffffffffffffffffffffff8316613482576131a19034935b61347c856130aa565b906130f0565b346134e7576131a1906134be7f1e0745a7db1623981f0b2a5d4232364c00787266eb75ad546f190e6cebe9bd955c6134b986613a92565b612fed565b935f7f27e098c505d44ec3574004bca052aabf76bd35004c182099d8c575fb238593b95d613473565b7fb0ec849e000000000000000000000000000000000000000000000000000000005f5260045ffd5b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016300361354e57565b7f0d89438e000000000000000000000000000000000000000000000000000000005f5260045ffd5b5473ffffffffffffffffffffffffffffffffffffffff161561359457565b7f486aa307000000000000000000000000000000000000000000000000000000005f5260045ffd5b91926136376101209473ffffffffffffffffffffffffffffffffffffffff61364f999794168552602085019073ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b60c083015260e082015281610100820152019161306c565b90565b9073ffffffffffffffffffffffffffffffffffffffff60206131a1949361368185848351168660801d906130f0565b01511690600f0b906130f0565b62ffffff16620f424081116136a05750565b7f14002113000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b9061364f95936137486101609473ffffffffffffffffffffffffffffffffffffffff61377794168552602085019073ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b8051600290810b60c08501526020820151900b60e0840152604081015161010084015260600151610120830152565b81610140820152019161306c565b9081600f0b9182036130c857565b926138419061381261364f99979473ffffffffffffffffffffffffffffffffffffffff6101a09895168752602087019073ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b8051600290810b60c08701526020820151900b60e0860152604081015161010086015260600151610120850152565b61014083015261016082015281610180820152019161306c565b939590919296945f9673ffffffffffffffffffffffffffffffffffffffff861633146139ac57885f6040870151135f1461393b5761040087166138a2575b50505050505050565b61392e9799985092613927969594926138ef9261391b956040519788967f9f063efc0000000000000000000000000000000000000000000000000000000060208901523360248901613793565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612e2e565b6002821615159161459f565b80926145bf565b915f808080808080613899565b95949392919061010086166139535750505050505050565b61392e979950869850916138ef916139a09493613927986040519788967f6c2bbe7e0000000000000000000000000000000000000000000000000000000060208901523360248901613793565b6001821615159161459f565b505f96505050505050565b608081161580613a69575b613a3f57604081161580613a5d575b613a3f5761040081161580613a51575b613a3f5761010081161580613a45575b613a3f5773ffffffffffffffffffffffffffffffffffffffff8116613a1f575062ffffff1662800000141590565b613fff161590811591613a30575090565b62800000915062ffffff161490565b50505f90565b506001811615156139f1565b506002811615156139e1565b506004811615156139d1565b506008811615156139c2565b6280000062ffffff821614613a8d5761364f8161368e565b505f90565b73ffffffffffffffffffffffffffffffffffffffff1680613ab257504790565b6020602491604051928380927f70a082310000000000000000000000000000000000000000000000000000000082523060048301525afa9081156124c2575f91613afa575090565b90506020813d602011613b21575b81613b1560209383612e2e565b81010312610330575190565b3d9150613b08565b9190915f8382019384129112908015821691151617611d9457565b6020830151955f9586959194913373ffffffffffffffffffffffffffffffffffffffff851614613d2d5760808416613b7e575b5050505050565b613c66926138ef613c6092613c4c946040519586947f575e24b4000000000000000000000000000000000000000000000000000000006020870152336024870152613c16604487018c73ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b8051151560e487015260208101516101048701526040015173ffffffffffffffffffffffffffffffffffffffff16610124860152565b61014061014485015261016484019161306c565b82613f25565b916060835103613d05576040015162ffffff166280000014613cf9575b600816613c94575b80808080613b77565b604001519250608083901d600f0b8015613c8b57613cb5905f861295613b29565b9315613cf1575f84135b613cc9575f613c8b565b7ffa0b71d6000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f8412613cbf565b60608201519350613c83565b7f1e048e1d000000000000000000000000000000000000000000000000000000005f5260045ffd5b505f965086955050505050565b90600f0b90600f0b01907fffffffffffffffffffffffffffffffff8000000000000000000000000000000082126f7fffffffffffffffffffffffffffffff831317611d9457565b9196959394929473ffffffffffffffffffffffffffffffffffffffff83163314613f18578460801d94600f0b938860408516613e40575b50505050505f9481600f0b15801590613e34575b613dd8575b5050509190565b613e0f9395505f60208201511290511515145f14613e17576fffffffffffffffffffffffffffffffff169060801b175b80936145bf565b5f8080613dd1565b906fffffffffffffffffffffffffffffffff169060801b17613e08565b5082600f0b1515613dcc565b613efc613f08946138ef6118ed95613f0e999895613ee1613c16966040519788967fb47b2fb1000000000000000000000000000000000000000000000000000000006020890152336024890152604488019073ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b8c61014485015261016061016485015261018484019161306c565b6004821615159161459f565b90613d3a565b5f80808088613db8565b5050505050909150905f90565b9190918251925f8060208301958682865af115613fc3575050604051917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f3d011683016040523d83523d9060208401915f833e6020845110918215613f8f575b5050613d0557565b5190517fffffffff000000000000000000000000000000000000000000000000000000009182169116141590505f80613f87565b5183517fffffffff00000000000000000000000000000000000000000000000000000000811691600481106140d7575b50507fffffffff000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f3d01169173ffffffffffffffffffffffffffffffffffffffff604051947f90bfb865000000000000000000000000000000000000000000000000000000008652166004850152166024830152608060448301528060a00160648301523d60848301523d5f60a484013e7fa9e35b2f0000000000000000000000000000000000000000000000000000000060c4828401600460a4820152015260e40190fd5b7fffffffff000000000000000000000000000000000000000000000000000000009250829060040360031b1b16168280613ff3565b919060020b9060020b9081810761413a5705908160081d5f52602052600160ff60405f2092161b8154189055565b601c906044926040519163d4d8f3e683526020830152604082015201fd5b60020b908160ff1d82810118620d89e8811161449e5763ffffffff9192600182167001fffcb933bd6fad37aa2d162d1a59400102700100000000000000000000000000000000189160028116614482575b60048116614466575b6008811661444a575b6010811661442e575b60208116614412575b604081166143f6575b608081166143da575b61010081166143be575b61020081166143a2575b6104008116614386575b610800811661436a575b611000811661434e575b6120008116614332575b6140008116614316575b61800081166142fa575b6201000081166142de575b6202000081166142c3575b6204000081166142a8575b620800001661428f575b5f12614268575b0160201c90565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04614261565b6b048a170391f7dc42444e8fa290910260801c9061425a565b6d2216e584f5fa1ea926041bedfe9890920260801c91614250565b916e5d6af8dedb81196699c329225ee6040260801c91614245565b916f09aa508b5b7a84e1c677de54f3e99bc90260801c9161423a565b916f31be135f97d08fd981231505542fcfa60260801c9161422f565b916f70d869a156d2a1b890bb3df62baf32f70260801c91614225565b916fa9f746462d870fdf8a65dc1f90e061e50260801c9161421b565b916fd097f3bdfd2022b8845ad8f792aa58250260801c91614211565b916fe7159475a2c29b7443b29c7fa6e889d90260801c91614207565b916ff3392b0822b70005940c7a398e4b70f30260801c916141fd565b916ff987a7253ac413176f2b074cf7815e540260801c916141f3565b916ffcbe86c7900a88aedcffc83b479aa3a40260801c916141e9565b916ffe5dee046a99a2a811c461f1969c30530260801c916141df565b916fff2ea16466c96a3843ec78b326b528610260801c916141d6565b916fff973b41fa98c081472e6896dfb254c00260801c916141cd565b916fffcb9843d60f6159c9db58835c9266440260801c916141c4565b916fffe5caca7e10e4e61c3624eaa0941cd00260801c916141bb565b916ffff2e50f5f656932ef12357cf3c7fdcc0260801c916141b2565b916ffff97272373d413259a46990580e213a0260801c916141a9565b827f8b86327a000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b905f83600f0b125f146144ff576144f5925f036fffffffffffffffffffffffffffffffff1691615a3d565b5f81126130c85790565b61451b926fffffffffffffffffffffffffffffffff16916159e2565b5f81126130c8575f0390565b905f83600f0b125f14614552576144f5925f036fffffffffffffffffffffffffffffffff1691615b34565b61451b926fffffffffffffffffffffffffffffffff1691615a7d565b906fffffffffffffffffffffffffffffffff90600f0b911601908160801c61459257565b6393dafdf15f526004601cfd5b906145a991613f25565b9015613a8d576040815103613d05576040015190565b6145e2906145d48360801d8260801d03613785565b92600f0b90600f0b03613785565b6fffffffffffffffffffffffffffffffff169060801b1790565b73fffd8963efd1fc6a506488495d951d516396168273ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffd895d830116116148e05777ffffffffffffffffffffffffffffffffffffffff000000008160201b168060ff61467983615bdb565b1691608083106148d457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8182011c5b800280607f1c8160ff1c1c800280607f1c8160ff1c1c800280607f1c8160ff1c1c800280607f1c8160ff1c1c800280607f1c8160ff1c1c800280607f1c8160ff1c1c80029081607f1c8260ff1c1c80029283607f1c8460ff1c1c80029485607f1c8660ff1c1c80029687607f1c8860ff1c1c80029889607f1c8a60ff1c1c80029a8b607f1c8c60ff1c1c80029c8d80607f1c9060ff1c1c800260cd1c6604000000000000169d60cc1c6608000000000000169c60cb1c6610000000000000169b60ca1c6620000000000000169a60c91c6640000000000000169960c81c6680000000000000169860c71c670100000000000000169760c61c670200000000000000169660c51c670400000000000000169560c41c670800000000000000169460c31c671000000000000000169360c21c672000000000000000169260c11c674000000000000000169160c01c67800000000000000016907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800160401b1717171717171717171717171717693627a301d71055774c85027ffffffffffffffffffffffffffffffffffd709b7e5480fba5a50fed5e62ffc556810160801d60020b906fdb2df09e81959a81455e260799a0632f0160801d60020b918282145f146148915750905090565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff6148c584614158565b16116148cf575090565b905090565b905081607f031b6146a9565b73ffffffffffffffffffffffffffffffffffffffff907f61487524000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b811561492c570490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b6040519290915f61496985612df6565b5f855260208501925f845260408601955f875280968654956040860151159586155f146156f557610fff8860b81c16945b8151925f948a73ffffffffffffffffffffffffffffffffffffffff16918288528b60a01c60020b90526fffffffffffffffffffffffffffffffff60038d0154169052608083015162400000811615155f146156e65762bfffff166149fd8161368e565b61ffff88166156cb575b8096620f424062ffffff8316101561569a575b8451156156845750508861562457606083019073ffffffffffffffffffffffffffffffffffffffff825116818110156155ed5750505173ffffffffffffffffffffffffffffffffffffffff166401000276a38111156155c257505b604051986101008a018a811067ffffffffffffffff821117611eb1576040525f8a525f60208b01525f60408b01525f60608b01525f60808b01525f60a08b01525f60c08b015288155f146155b45760018b0154949390945b60e08b01525b8015801561557a575b6154205788868d8c8e73ffffffffffffffffffffffffffffffffffffffff8351168252602083015160020b602089015160020b90815f8183071291050386155f14615275576fffffffffffffffffffffffffffffffff937ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2761860409460019484600560ff60609716938260020b60081d890b5f5201602052875f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8460ff031c9054169283151593845f146152635790614bb760ff92615bdb565b90031660020b900360020b0260020b5b905b15158684015260020b8060208401521315615238575b620d89e8602082015160020b121561522a575b73ffffffffffffffffffffffffffffffffffffffff614c17602083015160020b614158565b16918291015273ffffffffffffffffffffffffffffffffffffffff8551169673ffffffffffffffffffffffffffffffffffffffff60608c0151169283911516818310189118021892015116928d73ffffffffffffffffffffffffffffffffffffffff8316821015915f87125f1461507f5762ffffff8516620f424003614c9f81895f03615785565b94841561506e57614cb1888483615a7d565b955b868110614fb257509660a093929173ffffffffffffffffffffffffffffffffffffffff98978891620f424062ffffff8316145f14614f9e575050865b955b15614f905791614d0092615a3d565b925b60c0820152015260808d0152168c525f8351135f14614f605760a08a0151905f82126130c8570392614d3d60808b015160c08c015190612ffa565b5f81126130c8578103908113600116611d9457935b61ffff8716614f18575b6fffffffffffffffffffffffffffffffff60408d01511680614efe575b5073ffffffffffffffffffffffffffffffffffffffff8c511673ffffffffffffffffffffffffffffffffffffffff60608c01511681145f14614ec2575060408a0151614e10575b88614e03577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208b015160020b0160020b5b60020b60208d01525b9392614ad3565b60208a015160020b614df3565b88614e96576fffffffffffffffffffffffffffffffff614e7d8d8d8d600460e08201519260206002820154935b015160020b60020b5f520160205260405f2091600183019081549003905560028201908154900390555460801d908c15614e88575b60400151831661456e565b1660408d0152614dc0565b5f91909103600f0b90614e72565b6fffffffffffffffffffffffffffffffff614e7d8d8d8d6004600183015492602060e084015193614e3d565b73ffffffffffffffffffffffffffffffffffffffff8b51168103614ee7575b50614dfc565b614ef0906145fc565b60020b60208d01525f614ee1565b60c08b015160801b0460e08b01510160e08b01525f614d79565b9662ffffff861661ffff881603614f435760c08a0151905b8160c08c01510360c08c01520196614d5c565b620f424060808b015161ffff89169060c08d015101020490614f30565b60808a015160c08b015101905f82126130c857019260a08a01515f81126130c857614f8a91613b29565b93614d52565b614f9992615b34565b614d00565b62ffffff614fad921689615c68565b614cef565b9650505092505082918415811517615061578e60a09173ffffffffffffffffffffffffffffffffffffffff96845f14614ffc57614ff0878284615d07565b80978a015f0395614cf1565b87871161503a576150356150306150286fffffffffffffffffffffffffffffffff84168a60601b614922565b8a8516612ffa565b615d9b565b614ff0565b61503561503061505c6fffffffffffffffffffffffffffffffff84168a61588a565b615028565b634f2461b85f526004601cfd5b6150798882856159e2565b95614cb3565b9193509190831561521957615095858284615a3d565b915b8287106150f7579073ffffffffffffffffffffffffffffffffffffffff9560a09280965b156150e857916150ca92615a7d565b925b6150e362ffffff8d16620f42408190039086615c68565b614d02565b6150f1926159e2565b926150cc565b50915050838315821517615061578d83156151ef575073ffffffffffffffffffffffffffffffffffffffff851161519c578460601b6fffffffffffffffffffffffffffffffff851680820615159104015b73ffffffffffffffffffffffffffffffffffffffff8316928184111561518f578f939573ffffffffffffffffffffffffffffffffffffffff60a093819803165b80966150bb565b634323a5555f526004601cfd5b6fffffffffffffffffffffffffffffffff84166151c7816c0100000000000000000000000088615943565b90801561492c576c010000000000000000000000008709156151485760010180615148575f80fd5b9180856152148873ffffffffffffffffffffffffffffffffffffffff9860a095615c91565b615188565b615224858383615b34565b91615097565b620d89e86020820152614bf2565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276186020820152614bdf565b5060020b900360020b0260020b614bc7565b60019194939650600592955001938460020b60081d60010b5f520160205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600160ff86161b0119905416908d8b831592831597885f146153c15750505050610330578f9160018f8f96907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276186060928f989560409660ff896fffffffffffffffffffffffffffffffff9a5f03166101e07f804040554300526644320000502061067405302602000010750620017611707760fc7fb6db6db6ddddddddd34d34d349249249210842108c6318c639ce739cffffffff840260f81c161b60f71c167e1f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405601f85851693831c63d76453e004161a17031660020b9060020b0160020b0260020b5b90614bc9565b90956fffffffffffffffffffffffffffffffff955060409450600193987ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618918960ff6060969b811681031660020b9060020b0160020b0260020b6153bb565b949891955099969298919598602088015160a01b76ffffff0000000000000000000000000000000000000000167fffffffffffffffffff000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8a51169216171782556fffffffffffffffffffffffffffffffff6003830154166fffffffffffffffffffffffffffffffff604089015116809103615535575b5082156155265760e060029101519101555b825190155f82121461551057506154ee6154f69293613785565b925103613785565b6fffffffffffffffffffffffffffffffff169060801b1793565b6154f69250906155209103613785565b91613785565b60e060019101519101556154d4565b6fffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffff000000000000000000000000000000006003840154161760038301555f6154c2565b5073ffffffffffffffffffffffffffffffffffffffff8c511673ffffffffffffffffffffffffffffffffffffffff60608501511614614adc565b60028b015494939094614acd565b7f9e4d7cc7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b60449250604051917f7c9c6e8f00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b606083019073ffffffffffffffffffffffffffffffffffffffff825116818111156155ed5750505173ffffffffffffffffffffffffffffffffffffffff1673fffd8963efd1fc6a506488495d951d5263988d268110156155c25750614a75565b9a509a50509950505050505050505f925f929190565b5f85511315614a1a577f96206246000000000000000000000000000000000000000000000000000000005f5260045ffd5b62ffffff610fff89169116620f424081830204910103614a07565b508960d01c62ffffff166149fd565b610fff8860c41c169461499a565b90808202917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828209918380841093039280840393847001000000000000000000000000000000001115610330571461577c57700100000000000000000000000000000000910990828211900360801b910360801c1790565b50505060801c90565b818102907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83820990828083109203918083039283620f424011156103305714615804577fde8f6cefed634549b62c77574f722e1ac57e23f24d8fd5cb790fb65668c2613993620f4240910990828211900360fa1b910360061c170290565b5050620f424091500490565b90808202917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828209918380841093039280840393846c0100000000000000000000000011156103305714615881576c01000000000000000000000000910990828211900360a01b910360601c1790565b50505060601c90565b908160601b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6c01000000000000000000000000840992828085109403938085039485841115610330571461593c576c0100000000000000000000000082910981805f03168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b5091500490565b91818302917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8185099383808610950394808603958685111561033057146159da579082910981805f03168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b505091500490565b6fffffffffffffffffffffffffffffffff6c010000000000000000000000009173ffffffffffffffffffffffffffffffffffffffff80600195169116038060ff1d90810118931692615a348185615810565b93091515160190565b6fffffffffffffffffffffffffffffffff9073ffffffffffffffffffffffffffffffffffffffff8061364f9594169116038060ff1d908101189116615810565b9073ffffffffffffffffffffffffffffffffffffffff811673ffffffffffffffffffffffffffffffffffffffff831611615b2e575b73ffffffffffffffffffffffffffffffffffffffff8216928315615b22577bffffffffffffffffffffffffffffffff00000000000000000000000073ffffffffffffffffffffffffffffffffffffffff615b16948185169403169160601b16615c68565b90808206151591040190565b62bfc9215f526004601cfd5b90615ab2565b73ffffffffffffffffffffffffffffffffffffffff821673ffffffffffffffffffffffffffffffffffffffff821611615bd5575b73ffffffffffffffffffffffffffffffffffffffff8116918215615b225761364f937bffffffffffffffffffffffffffffffff00000000000000000000000073ffffffffffffffffffffffffffffffffffffffff615bd0948185169403169160601b16615943565b614922565b90615b68565b8015610330577f07060605060205000602030205040001060502050303040105050304000000006f8421084210842108cc6318c6db6d54be826fffffffffffffffffffffffffffffffff1060071b83811c67ffffffffffffffff1060061b1783811c63ffffffff1060051b1783811c61ffff1060041b1783811c60ff1060031b1792831c1c601f161a1790565b929190615c76828286615943565b93821561492c5709615c8457565b9060010190811561033057565b91908115615d02577bffffffffffffffffffffffffffffffff00000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9160601b169216918282029183838311918404141615615cf55761364f9261503092820391615c68565b63f5c787f15f526004601cfd5b505090565b90918015615d955773ffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffff000000000000000000000000819460601b16921680820281615d578483614922565b14615d7d575b5090615d6c615d719284614922565b612ffa565b80820615159104011690565b8301838110615d5d579150615d9192615c68565b1690565b50905090565b9073ffffffffffffffffffffffffffffffffffffffff82169182036130c85756fea164736f6c634300081a000a"; + } +} From 9624a51a46572d459f382e7060907f3073fa40ef Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 6 Mar 2025 15:32:19 +0900 Subject: [PATCH 208/312] update --- README.md | 7 +++ foundry.toml | 4 -- script/DeployPool.s.sol | 50 ++++++++++++++----- script/DeployProtocol.s.sol | 4 +- script/README.md | 9 +--- script/SetOperatorAndActivatePool.s.sol | 31 ------------ script/SwapExactIn.s.sol | 10 ++-- script/json/DeployPool_input.json | 12 +++-- .../SetOperatorAndActivatePool_input.json | 3 -- script/json/SwapExactIn_input.json | 7 +-- script/util/SwapUtil.sol | 30 ----------- src/EulerSwapFactory.sol | 49 ++++++++++++------ src/interfaces/IEulerSwapFactory.sol | 33 +++++++++++- 13 files changed, 131 insertions(+), 118 deletions(-) delete mode 100644 script/SetOperatorAndActivatePool.s.sol delete mode 100644 script/json/SetOperatorAndActivatePool_input.json delete mode 100644 script/util/SwapUtil.sol diff --git a/README.md b/README.md index 1315c99..f1ebc33 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,13 @@ forge doc --serve --port 4000 - EulerSwapFactory: 0x04C54FF83e4BC428FD1eDA2f41cdBd583A2e9cF8 - EulerSwapPeriphery: 0x64A8410D7D2ecF3Aaf32b6C3932e4586f3C42ecE +------ + +- EulerSwapFactory: 0xF75548aF02f1928CbE9015985D4Fcbf96d728544 +- EulerSwapPeriphery: 0x813D74E832b3d9E9451d8f0E871E877edf2a5A5f +- USDT-USDT pool: 0x2bFED8dBEb8e6226a15300AC77eE9130E52410fE + + ## Safety This software is experimental and is provided "as is" and "as available". diff --git a/foundry.toml b/foundry.toml index 774d433..c46a452 100644 --- a/foundry.toml +++ b/foundry.toml @@ -8,10 +8,6 @@ optimizer_runs = 10000 gas_reports = ["*"] fs_permissions = [{ access = "read-write", path = "./"}] -[doc] -out = "foundry-docs/" -title = "EulerSwap Contracts Documentation" - [rpc_endpoints] mainnet = "${MAINNET_RPC_URL}" base = "${BASE_RPC_URL}" diff --git a/script/DeployPool.s.sol b/script/DeployPool.s.sol index ea691b9..e1dedd6 100644 --- a/script/DeployPool.s.sol +++ b/script/DeployPool.s.sol @@ -2,36 +2,62 @@ pragma solidity ^0.8.0; import {ScriptUtil} from "./ScriptUtil.s.sol"; -import {IEulerSwapFactory, EulerSwapFactory} from "../src/EulerSwapFactory.sol"; +import {IEulerSwapFactory, IEulerSwap, EulerSwapFactory} from "../src/EulerSwapFactory.sol"; +import {IEVC, IEulerSwap} from "../src/EulerSwap.sol"; /// @title Script to deploy new pool. contract DeployPool is ScriptUtil { function run() public { // load wallet - uint256 deployerKey = vm.envUint("WALLET_PRIVATE_KEY"); - address deployerAddress = vm.rememberKey(deployerKey); + uint256 eulerAccountKey = vm.envUint("WALLET_PRIVATE_KEY"); + address eulerAccount = vm.rememberKey(eulerAccountKey); // load JSON file string memory inputScriptFileName = "DeployPool_input.json"; string memory json = _getJsonFile(inputScriptFileName); EulerSwapFactory factory = EulerSwapFactory(vm.parseJsonAddress(json, ".factory")); - IEulerSwapFactory.DeployParams memory params = IEulerSwapFactory.DeployParams({ + IEulerSwap.Params memory poolParams = IEulerSwap.Params({ vault0: vm.parseJsonAddress(json, ".vault0"), vault1: vm.parseJsonAddress(json, ".vault1"), - swapAccount: vm.parseJsonAddress(json, ".swapAccount"), - fee: vm.parseJsonUint(json, ".fee"), + eulerAccount: eulerAccount, + equilibriumReserve0: uint112(vm.parseJsonUint(json, ".equilibriumReserve0")), + equilibriumReserve1: uint112(vm.parseJsonUint(json, ".equilibriumReserve1")), + currReserve0: uint112(vm.parseJsonUint(json, ".currReserve0")), + currReserve1: uint112(vm.parseJsonUint(json, ".currReserve1")), + fee: vm.parseJsonUint(json, ".fee") + }); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams({ priceX: vm.parseJsonUint(json, ".priceX"), priceY: vm.parseJsonUint(json, ".priceY"), concentrationX: vm.parseJsonUint(json, ".concentrationX"), - concentrationY: vm.parseJsonUint(json, ".concentrationY"), - debtLimit0: uint112(vm.parseJsonUint(json, ".debtLimit0")), - debtLimit1: uint112(vm.parseJsonUint(json, ".debtLimit1")) + concentrationY: vm.parseJsonUint(json, ".concentrationY") }); + bytes32 salt = bytes32(uint256(vm.parseJsonUint(json, ".salt"))); - vm.startBroadcast(deployerAddress); + IEVC evc = IEVC(factory.EVC()); + address predictedPoolAddress = factory.computePoolAddress(poolParams, curveParams, salt); - address pool = factory.deployPool(params); + IEVC.BatchItem[] memory items = new IEVC.BatchItem[](2); + + items[0] = IEVC.BatchItem({ + onBehalfOfAccount: address(0), + targetContract: address(evc), + value: 0, + data: abi.encodeCall(evc.setAccountOperator, (eulerAccount, predictedPoolAddress, true)) + }); + items[1] = IEVC.BatchItem({ + onBehalfOfAccount: eulerAccount, + targetContract: address(factory), + value: 0, + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) + }); + + vm.startBroadcast(eulerAccount); + evc.batch(items); + vm.stopBroadcast(); + + address pool = factory.eulerAccountToPool(eulerAccount); string memory outputScriptFileName = "DeployPool_output.json"; @@ -39,7 +65,5 @@ contract DeployPool is ScriptUtil { object = vm.serializeAddress("factory", "deployedPool", pool); vm.writeJson(object, string.concat(vm.projectRoot(), "/script/json/out/", outputScriptFileName)); - - vm.stopBroadcast(); } } diff --git a/script/DeployProtocol.s.sol b/script/DeployProtocol.s.sol index d478fe2..ee87fb9 100644 --- a/script/DeployProtocol.s.sol +++ b/script/DeployProtocol.s.sol @@ -20,8 +20,8 @@ contract DeployProtocol is ScriptUtil { vm.startBroadcast(deployerAddress); - new EulerSwapFactory(); - new EulerSwapPeriphery(evc); + new EulerSwapFactory(evc); + new EulerSwapPeriphery(); vm.stopBroadcast(); } diff --git a/script/README.md b/script/README.md index d03cd16..eee6f22 100644 --- a/script/README.md +++ b/script/README.md @@ -14,16 +14,11 @@ After filling the `.env` file, make sure to run: `source .env` in your terminal. ## Deploy new pool - Fill the `DeployPool_input.json` file with the needed inputs. +- In pool deployment, the `eulerAccount` address is the deployer address, so we derive the address from the attached private key in the `.env` file. - Run `forge script ./script/DeployPool.s.sol --rpc-url network_name --broadcast --slow` -## Activate new pool - -- Fill the `SetOperatorAndActivatePool_input.json` file with the needed inputs. -- Run `forge script ./script/SetOperatorAndActivatePool.s.sol --rpc-url network_name --broadcast --slow` - ## Exact in swap -- Fill the `SwapExactIn_input.json` file with the needed inputs. For the `swapUtil` field, use the address of the `SwapUtil` contract deployed in the network you are using: - - For mainnet, use `0xcdd2d349eeD309a0016C9A17f01bF1670913708b` +- Fill the `SwapExactIn_input.json` file with the needed inputs. - Run `forge script ./script/SwapExactIn.s.sol --rpc-url network_name --broadcast --slow` diff --git a/script/SetOperatorAndActivatePool.s.sol b/script/SetOperatorAndActivatePool.s.sol deleted file mode 100644 index 98c050d..0000000 --- a/script/SetOperatorAndActivatePool.s.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {ScriptUtil} from "./ScriptUtil.s.sol"; -import {EulerSwap, IEVC} from "../src/EulerSwap.sol"; - -import "forge-std/console2.sol"; - -/// @title Script to deploy new pool. -contract SetOperatorAndActivatePool is ScriptUtil { - function run() public { - // load wallet - uint256 deployerKey = vm.envUint("WALLET_PRIVATE_KEY"); - address deployerAddress = vm.rememberKey(deployerKey); - - // load JSON file - string memory inputScriptFileName = "SetOperatorAndActivatePool_input.json"; - string memory json = _getJsonFile(inputScriptFileName); - - EulerSwap pool = EulerSwap(vm.parseJsonAddress(json, ".pool")); - IEVC evc = IEVC(pool.EVC()); - - vm.startBroadcast(deployerAddress); - - evc.setAccountOperator(deployerAddress, address(pool), true); - - pool.activate(); - - vm.stopBroadcast(); - } -} diff --git a/script/SwapExactIn.s.sol b/script/SwapExactIn.s.sol index ff0e3ef..149f58f 100644 --- a/script/SwapExactIn.s.sol +++ b/script/SwapExactIn.s.sol @@ -3,8 +3,7 @@ pragma solidity ^0.8.0; import {ScriptUtil} from "./ScriptUtil.s.sol"; import {IERC20, SafeERC20, EulerSwap} from "../src/EulerSwap.sol"; -import {SwapUtil} from "./util/SwapUtil.sol"; - +import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; contract SwapExactIn is ScriptUtil { using SafeERC20 for IERC20; @@ -17,17 +16,18 @@ contract SwapExactIn is ScriptUtil { string memory inputScriptFileName = "SwapExactIn_input.json"; string memory json = _getJsonFile(inputScriptFileName); - SwapUtil swapUtil = SwapUtil(vm.parseJsonAddress(json, ".swapUtil")); // Do not change address of this one unless u manually deploy new one + EulerSwapPeriphery periphery = EulerSwapPeriphery(vm.parseJsonAddress(json, ".periphery")); EulerSwap pool = EulerSwap(vm.parseJsonAddress(json, ".pool")); address tokenIn = vm.parseJsonAddress(json, ".tokenIn"); address tokenOut = vm.parseJsonAddress(json, ".tokenOut"); uint256 amountIn = vm.parseJsonUint(json, ".amountIn"); + uint256 amountOutMin = vm.parseJsonUint(json, ".amountOutMin"); vm.startBroadcast(swapperAddress); - IERC20(tokenIn).forceApprove(address(swapUtil), amountIn); + IERC20(tokenIn).forceApprove(address(periphery), amountIn); - swapUtil.executeSwap(address(pool), tokenIn, tokenOut, amountIn, true); + periphery.swapExactIn(address(pool), tokenIn, tokenOut, amountIn, amountOutMin); vm.stopBroadcast(); } diff --git a/script/json/DeployPool_input.json b/script/json/DeployPool_input.json index ea5e730..bd53048 100644 --- a/script/json/DeployPool_input.json +++ b/script/json/DeployPool_input.json @@ -1,13 +1,15 @@ { - "factory": "0x04C54FF83e4BC428FD1eDA2f41cdBd583A2e9cF8", + "factory": "0xF75548aF02f1928CbE9015985D4Fcbf96d728544", + "salt": "1", "vault0": "0xa66957e58b60d6b92b850c8773a9ff9b0ba96a65", "vault1": "0x4212e01c7c8e1c21dea6030c74ae2084f5337bd1", - "swapAccount": "0x603765f9e9B8E3CBACbdf7A6e963B7EAD77AE86f", + "equilibriumReserve0": 2000e6, + "equilibriumReserve1": 2000e6, + "currReserve0": 2000e6, + "currReserve1": 2000e6, "fee": 0, "priceX": 1e18, "priceY": 1e18, "concentrationX": 0.97e18, - "concentrationY": 0.97e18, - "debtLimit0": 2000e6, - "debtLimit1": 2000e6 + "concentrationY": 0.97e18 } \ No newline at end of file diff --git a/script/json/SetOperatorAndActivatePool_input.json b/script/json/SetOperatorAndActivatePool_input.json deleted file mode 100644 index e080e1d..0000000 --- a/script/json/SetOperatorAndActivatePool_input.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "pool": "0x67c30405250e395f31d661274352da404e624682" -} \ No newline at end of file diff --git a/script/json/SwapExactIn_input.json b/script/json/SwapExactIn_input.json index ce396e8..3836023 100644 --- a/script/json/SwapExactIn_input.json +++ b/script/json/SwapExactIn_input.json @@ -1,7 +1,8 @@ { - "pool": "0x67C30405250e395f31d661274352dA404e624682", - "swapUtil": "0xcdd2d349eeD309a0016C9A17f01bF1670913708b", + "periphery": "0x813D74E832b3d9E9451d8f0E871E877edf2a5A5f", + "pool": "0x2bFED8dBEb8e6226a15300AC77eE9130E52410fE", "tokenIn": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "tokenOut": "0xdAC17F958D2ee523a2206206994597C13D831ec7", - "amountIn": 9e6 + "amountIn": 4e6, + "amountOutMin": 3.9e6 } \ No newline at end of file diff --git a/script/util/SwapUtil.sol b/script/util/SwapUtil.sol deleted file mode 100644 index 4d1772f..0000000 --- a/script/util/SwapUtil.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {IEulerSwapPeriphery} from "../../src/interfaces/IEulerSwapPeriphery.sol"; -import {IERC20, IEulerSwap, SafeERC20} from "../../src/EulerSwap.sol"; - -// This is not meant to be run in production, just for testing purposes -contract SwapUtil { - using SafeERC20 for IERC20; - - IEulerSwapPeriphery public immutable periphery; - - constructor(address peripheryAddr) { - periphery = IEulerSwapPeriphery(peripheryAddr); - } - - function executeSwap(address pool, address tokenIn, address tokenOut, uint256 amount, bool isExactIn) external { - bool isAsset0In = tokenIn < tokenOut; - - (uint256 amountIn, uint256 amountOut) = (isExactIn) - ? (amount, periphery.quoteExactInput(address(pool), tokenIn, tokenOut, amount)) - : (periphery.quoteExactOutput(address(pool), tokenIn, tokenOut, amount), amount); - - IERC20(tokenIn).safeTransferFrom(msg.sender, address(pool), amountIn); - - (isAsset0In) - ? IEulerSwap(pool).swap(0, amountOut, msg.sender, "") - : IEulerSwap(pool).swap(amountOut, 0, msg.sender, ""); - } -} diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 28ae63d..c3b6c9c 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -21,6 +21,8 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { address vault1, uint256 indexed feeMultiplier, address eulerAccount, + uint256 reserve0, + uint256 reserve1, uint256 priceX, uint256 priceY, uint256 concentrationX, @@ -35,14 +37,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { constructor(address evc) EVCUtil(evc) {} - /// @notice Deploy a new EulerSwap pool with the given parameters - /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from - /// the euler account address and provided salt parameter. This allows the pool address to be - /// predicted before deployment. - /// @param params Core pool parameters including vaults, account, and fee settings - /// @param curveParams Parameters defining the curve shape including prices and concentrations - /// @param salt Unique value to generate deterministic pool address - /// @return Address of the newly deployed pool + /// @inheritdoc IEulerSwapFactory function deployPool(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams, bytes32 salt) external returns (address) @@ -64,6 +59,8 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { params.vault1, pool.feeMultiplier(), params.eulerAccount, + params.currReserve0, + params.currReserve1, curveParams.priceX, curveParams.priceY, curveParams.concentrationX, @@ -74,16 +71,40 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { return address(pool); } - /// @notice Get the length of `allPools` array. - /// @return `allPools` length. + /// @inheritdoc IEulerSwapFactory + function computePoolAddress( + IEulerSwap.Params memory poolParams, + IEulerSwap.CurveParams memory curveParams, + bytes32 salt + ) external view returns (address) { + return address( + uint160( + uint256( + keccak256( + abi.encodePacked( + bytes1(0xff), + address(this), + keccak256(abi.encode(address(poolParams.eulerAccount), salt)), + keccak256( + abi.encodePacked(type(EulerSwap).creationCode, abi.encode(poolParams, curveParams)) + ) + ) + ) + ) + ) + ); + } + + function EVC() external view override(EVCUtil, IEulerSwapFactory) returns (address) { + return address(evc); + } + + /// @inheritdoc IEulerSwapFactory function allPoolsLength() external view returns (uint256) { return allPools.length; } - /// @notice Get a slice of the deployed pools array. - /// @param _start Start index of the slice. - /// @param _end End index of the slice. - /// @return An array containing the slice of the deployed pools. + /// @inheritdoc IEulerSwapFactory function getAllPoolsListSlice(uint256 _start, uint256 _end) external view returns (address[] memory) { uint256 length = allPools.length; if (_end == type(uint256).max) _end = length; diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol index 731e898..3d1b164 100644 --- a/src/interfaces/IEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -4,11 +4,42 @@ pragma solidity >=0.8.0; import {IEulerSwap} from "./IEulerSwap.sol"; interface IEulerSwapFactory { + /// @notice Deploy a new EulerSwap pool with the given parameters + /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from + /// the euler account address and provided salt parameter. This allows the pool address to be + /// predicted before deployment. + /// @param params Core pool parameters including vaults, account, and fee settings + /// @param curveParams Parameters defining the curve shape including prices and concentrations + /// @param salt Unique value to generate deterministic pool address + /// @return Address of the newly deployed pool function deployPool(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams, bytes32 salt) external returns (address); - function allPools(uint256 index) external view returns (address); + /// @notice Compute the address of a new EulerSwap pool with the given parameters + /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from + /// the euler account address and provided salt parameter. This allows the pool address to be + /// predicted before deployment. + /// @param poolParams Core pool parameters including vaults, account, and fee settings + /// @param curveParams Parameters defining the curve shape including prices and concentrations + /// @param salt Unique value to generate deterministic pool address + /// @return Address of the newly deployed pool + function computePoolAddress( + IEulerSwap.Params memory poolParams, + IEulerSwap.CurveParams memory curveParams, + bytes32 salt + ) external view returns (address); + function EVC() external view returns (address); + /// @notice Get the length of `allPools` array. + /// @return `allPools` length. function allPoolsLength() external view returns (uint256); + /// @notice Get the address of the pool at the given index in the `allPools` array. + /// @param index The index of the pool to retrieve. + /// @return The address of the pool at the given index. + function allPools(uint256 index) external view returns (address); + /// @notice Get a slice of the deployed pools array. + /// @param start Start index of the slice. + /// @param end End index of the slice. + /// @return An array containing the slice of the deployed pools. function getAllPoolsListSlice(uint256 start, uint256 end) external view returns (address[] memory); } From 15918ec7971d9dfecd44d113eb1f71b2b558d025 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Thu, 6 Mar 2025 15:57:09 -0500 Subject: [PATCH 209/312] stub beforeSwap --- src/EulerSwapHook.sol | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/EulerSwapHook.sol b/src/EulerSwapHook.sol index 3c24db3..cb333ff 100644 --- a/src/EulerSwapHook.sol +++ b/src/EulerSwapHook.sol @@ -7,6 +7,7 @@ import {PoolKey} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; +import {BeforeSwapDelta, BeforeSwapDeltaLibrary} from "@uniswap/v4-core/src/types/BeforeSwapDelta.sol"; import {EulerSwap, IEulerSwap, IEVault} from "./EulerSwap.sol"; contract EulerSwapHook is EulerSwap, BaseHook { @@ -34,6 +35,15 @@ contract EulerSwapHook is EulerSwap, BaseHook { poolManager.initialize(poolKey, 79228162514264337593543950336); } + function _beforeSwap(address, PoolKey calldata, IPoolManager.SwapParams calldata, bytes calldata) + internal + override + returns (bytes4, BeforeSwapDelta, uint24) + { + // TODO: implement custom curve logic, using depositAssets/withdrawAssets + return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0); + } + // TODO: fix salt mining & verification for the hook function getHookPermissions() public pure override returns (Hooks.Permissions memory) {} function validateHookAddress(BaseHook) internal pure override {} From 727d8b11d37f03743b7819801ddec8fb0bdddb53 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Thu, 6 Mar 2025 23:35:03 -0500 Subject: [PATCH 210/312] build out beforeSwap custom curve --- src/EulerSwapHook.sol | 56 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/src/EulerSwapHook.sol b/src/EulerSwapHook.sol index cb333ff..1a631ab 100644 --- a/src/EulerSwapHook.sol +++ b/src/EulerSwapHook.sol @@ -7,10 +7,15 @@ import {PoolKey} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; -import {BeforeSwapDelta, BeforeSwapDeltaLibrary} from "@uniswap/v4-core/src/types/BeforeSwapDelta.sol"; +import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol"; +import { + BeforeSwapDelta, toBeforeSwapDelta, BeforeSwapDeltaLibrary +} from "@uniswap/v4-core/src/types/BeforeSwapDelta.sol"; import {EulerSwap, IEulerSwap, IEVault} from "./EulerSwap.sol"; contract EulerSwapHook is EulerSwap, BaseHook { + using SafeCast for uint256; + PoolKey poolKey; constructor(IPoolManager _manager, Params memory params, CurveParams memory curveParams) @@ -35,13 +40,56 @@ contract EulerSwapHook is EulerSwap, BaseHook { poolManager.initialize(poolKey, 79228162514264337593543950336); } - function _beforeSwap(address, PoolKey calldata, IPoolManager.SwapParams calldata, bytes calldata) + function _beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata) internal override returns (bytes4, BeforeSwapDelta, uint24) { - // TODO: implement custom curve logic, using depositAssets/withdrawAssets - return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0); + // determine inbound/outbound token based on 0->1 or 1->0 swap + (Currency inputCurrency, Currency outputCurrency) = + params.zeroForOne ? (key.currency0, key.currency1) : (key.currency1, key.currency0); + bool isExactInput = params.amountSpecified < 0; + + // TODO: compute the open side of the trade, using computeQuote() ? + uint256 amountIn; + uint256 amountOut; + // uint256 amountIn = isExactInput ? uint256(-params.amountSpecified) : computeQuote(..., false); + // uint256 amountOut = isExactInput ? computeQuote(..., true) : uint256(params.amountSpecified); + + // take the input token, from the PoolManager to the Euler vault + // the debt will be paid by the swapper via the swap router + // TODO: can we optimize the transfer by pulling from PoolManager directly to Euler? + poolManager.take(inputCurrency, address(this), amountIn); + depositAssets(inputCurrency == key.currency0 ? vault0 : vault1, amountIn); + + // pay the output token, to the PoolManager from an Euler vault + // the credit will be forwarded to the swap router, which then forwards it to the swapper + poolManager.sync(outputCurrency); + withdrawAssets(outputCurrency == key.currency0 ? vault0 : vault1, amountOut, address(poolManager)); + poolManager.settle(); + + { + uint256 newReserve0 = inputCurrency == key.currency0 ? (reserve0 + amountIn) : (reserve0 - amountOut); + uint256 newReserve1 = inputCurrency == key.currency1 ? (reserve1 + amountIn) : (reserve1 - amountOut); + + require(newReserve0 <= type(uint112).max && newReserve1 <= type(uint112).max, Overflow()); + require(verify(newReserve0, newReserve1), CurveViolation()); + + reserve0 = uint112(newReserve0); + reserve1 = uint112(newReserve1); + } + + // return the delta to the PoolManager, so it can process the accounting + // exact input: + // specifiedDelta = positive, to offset the input token taken by the hook (negative delta) + // unspecifiedDelta = negative, to offset the credit of the output token paid by the hook (positive delta) + // exact output: + // specifiedDelta = negative, to offset the output token paid by the hook (positive delta) + // unspecifiedDelta = positive, to offset the input token taken by the hook (negative delta) + BeforeSwapDelta returnDelta = isExactInput + ? toBeforeSwapDelta(amountIn.toInt128(), -(amountOut.toInt128())) + : toBeforeSwapDelta(-(amountOut.toInt128()), amountIn.toInt128()); + return (BaseHook.beforeSwap.selector, returnDelta, 0); } // TODO: fix salt mining & verification for the hook From 0bf1a79ebdfe478842867b3daabcd935c50b3571 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Fri, 7 Mar 2025 16:35:48 -0500 Subject: [PATCH 211/312] revert virtual --- src/EulerSwap.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index a71e97c..a9e3695 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -102,7 +102,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { /// @inheritdoc IEulerSwap function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external - virtual callThroughEVC nonReentrant { From 9660bc2f30476117b5fa1f325190606ad05ad5aa Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 10 Mar 2025 10:03:59 +0900 Subject: [PATCH 212/312] chore: lint --- script/SwapExactIn.s.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/script/SwapExactIn.s.sol b/script/SwapExactIn.s.sol index 149f58f..87de3c2 100644 --- a/script/SwapExactIn.s.sol +++ b/script/SwapExactIn.s.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.0; import {ScriptUtil} from "./ScriptUtil.s.sol"; import {IERC20, SafeERC20, EulerSwap} from "../src/EulerSwap.sol"; import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; + contract SwapExactIn is ScriptUtil { using SafeERC20 for IERC20; From 0c6238c33b38f5617e33d7b73b698fa721ac73ab Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 10 Mar 2025 19:05:18 -0400 Subject: [PATCH 213/312] remove unnecessary verification of equilibrium point, stricter verification of current reserves spearbit #4 and #5 (partial) --- src/EulerSwap.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index de30f0a..72233d4 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -96,9 +96,9 @@ contract EulerSwap is IEulerSwap, EVCUtil { // Validate reserves - require(verify(equilibriumReserve0, equilibriumReserve1), CurveViolation()); require(verify(reserve0, reserve1), CurveViolation()); - require(!verify(reserve0 > 0 ? reserve0 - 1 : 0, reserve1 > 0 ? reserve1 - 1 : 0), CurveViolation()); + require(!verify(reserve0 > 0 ? reserve0 - 1 : 0, reserve1), CurveViolation()); + require(!verify(reserve0, reserve1 > 0 ? reserve1 - 1 : 0), CurveViolation()); emit EulerSwapCreated(asset0Addr, asset1Addr); } From e44a49acb42df906c8728252d133feeebc8ed941 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 11 Mar 2025 20:10:15 -0400 Subject: [PATCH 214/312] prevent read-only re-entrancy in getReserves() spearbit #12 --- src/EulerSwap.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 72233d4..d3d7c27 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -154,6 +154,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { /// @inheritdoc IEulerSwap function getReserves() external view returns (uint112, uint112, uint32) { + require(status != 2, Locked()); return (reserve0, reserve1, status); } From fcd9fcf9b02b5c80d95206687338bda8006ccff4 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 11 Mar 2025 20:41:10 -0400 Subject: [PATCH 215/312] Avoid deposit() method when only repaying, to support borrow-only vaults spearbit #8 --- src/EulerSwap.sol | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index d3d7c27..8d8c436 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -221,23 +221,34 @@ contract EulerSwap is IEulerSwap, EVCUtil { /// @dev After successful deposit, if the user has any outstanding controller-enabled debt, it attempts to repay it. /// @dev If all debt is repaid, the controller is automatically disabled to reduce gas costs in future operations. function depositAssets(address vault, uint256 amount) internal returns (uint256) { - try IEVault(vault).deposit(amount, eulerAccount) {} - catch (bytes memory reason) { - require(bytes4(reason) == EVKErrors.E_ZeroShares.selector, DepositFailure(reason)); - return 0; - } + uint256 debt = myDebt(vault); + uint256 deposited; - if (IEVC(evc).isControllerEnabled(eulerAccount, vault)) { - IEVC(evc).call( - vault, eulerAccount, 0, abi.encodeCall(IBorrowing.repayWithShares, (type(uint256).max, eulerAccount)) - ); + if (debt > 0) { + uint256 repayAmount = amount > debt ? debt : amount; + + IEVault(vault).repay(repayAmount, eulerAccount); - if (myDebt(vault) == 0) { + amount -= repayAmount; + debt -= repayAmount; + deposited += repayAmount; + + if (debt == 0) { IEVC(evc).call(vault, eulerAccount, 0, abi.encodeCall(IRiskManager.disableController, ())); } } - return amount; + if (amount > 0) { + try IEVault(vault).deposit(amount, eulerAccount) {} + catch (bytes memory reason) { + require(bytes4(reason) == EVKErrors.E_ZeroShares.selector, DepositFailure(reason)); + return deposited; + } + + deposited += amount; + } + + return deposited; } /// @notice Approves tokens for a given vault, supporting both standard approvals and permit2 From e3c7a4098d4909b1fbc54393c8eef95f80edb1c7 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 11 Mar 2025 20:53:48 -0400 Subject: [PATCH 216/312] Make factory check that vaults are created by EVK factory spearbit #9 --- script/DeployProtocol.s.sol | 3 ++- script/json/DeployProtocol_input.json | 5 +++-- src/EulerSwap.sol | 2 -- src/EulerSwapFactory.sol | 12 +++++++++++- test/EulerSwapFactoryTest.t.sol | 2 +- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/script/DeployProtocol.s.sol b/script/DeployProtocol.s.sol index ee87fb9..04e4570 100644 --- a/script/DeployProtocol.s.sol +++ b/script/DeployProtocol.s.sol @@ -17,10 +17,11 @@ contract DeployProtocol is ScriptUtil { string memory json = _getJsonFile(inputScriptFileName); address evc = vm.parseJsonAddress(json, ".evc"); + address factory = vm.parseJsonAddress(json, ".factory"); vm.startBroadcast(deployerAddress); - new EulerSwapFactory(evc); + new EulerSwapFactory(evc, factory); new EulerSwapPeriphery(); vm.stopBroadcast(); diff --git a/script/json/DeployProtocol_input.json b/script/json/DeployProtocol_input.json index 0c26615..db6752a 100644 --- a/script/json/DeployProtocol_input.json +++ b/script/json/DeployProtocol_input.json @@ -1,3 +1,4 @@ { - "evc": "0x0C9a3dd6b8F28529d72d7f9cE918D493519EE383" -} \ No newline at end of file + "evc": "0x0C9a3dd6b8F28529d72d7f9cE918D493519EE383", + "factory": "0xF75548aF02f1928CbE9015985D4Fcbf96d728544" +} diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 8d8c436..f9a39de 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -50,7 +50,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { error Overflow(); error BadParam(); error AmountTooBig(); - error DifferentEVC(); error AssetsOutOfOrderOrEqual(); error CurveViolation(); error DepositFailure(bytes reason); @@ -70,7 +69,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { require(curveParams.priceX > 0 && curveParams.priceY > 0, BadParam()); require(curveParams.priceX <= 1e36 && curveParams.priceY <= 1e36, BadParam()); require(curveParams.concentrationX <= 1e18 && curveParams.concentrationY <= 1e18, BadParam()); - require(IEVault(params.vault0).EVC() == IEVault(params.vault1).EVC(), DifferentEVC()); address asset0Addr = IEVault(params.vault0).asset(); address asset1Addr = IEVault(params.vault1).asset(); diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index c3b6c9c..dcde2fd 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.27; import {IEulerSwapFactory, IEulerSwap} from "./interfaces/IEulerSwapFactory.sol"; import {EulerSwap} from "./EulerSwap.sol"; import {EVCUtil} from "ethereum-vault-connector/utils/EVCUtil.sol"; +import {GenericFactory} from "evk/GenericFactory/GenericFactory.sol"; /// @title EulerSwapFactory contract /// @custom:security-contact security@euler.xyz @@ -13,6 +14,8 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { address[] public allPools; /// @dev Mapping between euler account and deployed pool that is currently set as operator mapping(address eulerAccount => address operator) public eulerAccountToPool; + /// @dev Vaults must be deployed by this factory + address public immutable evkFactory; event PoolDeployed( address indexed asset0, @@ -34,8 +37,11 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { error Unauthorized(); error OldOperatorStillInstalled(); error OperatorNotInstalled(); + error InvalidVaultImplementation(); - constructor(address evc) EVCUtil(evc) {} + constructor(address evc, address evkFactory_) EVCUtil(evc) { + evkFactory = evkFactory_; + } /// @inheritdoc IEulerSwapFactory function deployPool(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams, bytes32 salt) @@ -43,6 +49,10 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { returns (address) { require(_msgSender() == params.eulerAccount, Unauthorized()); + require( + GenericFactory(evkFactory).isProxy(params.vault0) && GenericFactory(evkFactory).isProxy(params.vault1), + InvalidVaultImplementation() + ); EulerSwap pool = new EulerSwap{salt: keccak256(abi.encode(params.eulerAccount, salt))}(params, curveParams); diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index bae4701..fe9fb73 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -13,7 +13,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { super.setUp(); vm.prank(creator); - eulerSwapFactory = new EulerSwapFactory(address(evc)); + eulerSwapFactory = new EulerSwapFactory(address(evc), address(factory)); } function testDeployPool() public { From 6d35d8725632351f3e80bed74121cd9fd05033ca Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 11 Mar 2025 20:58:40 -0400 Subject: [PATCH 217/312] pass interfaces instead of raw addresses to internal functions spearbit #13 --- src/EulerSwapPeriphery.sol | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index 0c2bd74..2983e7e 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -24,7 +24,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { require(amountOut >= amountOutMin, AmountOutLessThanMin()); - swap(eulerSwap, tokenIn, tokenOut, amountIn, amountOut); + swap(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountIn, amountOut); } /// @inheritdoc IEulerSwapPeriphery @@ -35,7 +35,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { require(amountIn <= amountInMax, AmountInMoreThanMax()); - swap(eulerSwap, tokenIn, tokenOut, amountIn, amountOut); + swap(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountIn, amountOut); } /// @inheritdoc IEulerSwapPeriphery @@ -73,13 +73,13 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { /// @param tokenOut The address of the output token being received /// @param amountIn The amount of input tokens to swap /// @param amountOut The amount of output tokens to receive - function swap(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut) internal { - IERC20(tokenIn).safeTransferFrom(msg.sender, eulerSwap, amountIn); + function swap(IEulerSwap eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut) + internal + { + IERC20(tokenIn).safeTransferFrom(msg.sender, address(eulerSwap), amountIn); bool isAsset0In = tokenIn < tokenOut; - (isAsset0In) - ? IEulerSwap(eulerSwap).swap(0, amountOut, msg.sender, "") - : IEulerSwap(eulerSwap).swap(amountOut, 0, msg.sender, ""); + (isAsset0In) ? eulerSwap.swap(0, amountOut, msg.sender, "") : eulerSwap.swap(amountOut, 0, msg.sender, ""); } /// @dev Computes the quote for a swap by applying fees and validating state conditions From 12efc8a6801ddc6e880dec8c2738795e5035989c Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 11 Mar 2025 20:59:09 -0400 Subject: [PATCH 218/312] typos and docs spearbit #13 --- docs/architecture.md | 2 +- src/EulerSwap.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index fcbad7c..2415cde 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -43,7 +43,7 @@ Virtual reserves control the maximum debt that the EulerSwap contract will attem ### Reserve synchronisation -The EulerSwap contract tracks what it believes the reserves to be by caching their values in storage. These reserves are updated on each swap. However, since the balance is not actually held by the EulerSwap contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest is accrued, or suddenly if the holder moves funds or the position is liquidated. When this occurs, the `syncVirtualReserves()` should be invoked. This determines the actual balances (and debts) of the holder and adjusts them by the configured virtual reserve levels. +The EulerSwap contract tracks what it believes the reserves to be by caching their values in storage. These reserves are updated on each swap. However, since the balance is not actually held by the EulerSwap contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest is accrued, or suddenly if the holder moves funds or the position is liquidated. When this occurs, the EulerSwap operator should be uninstalled and a new, updated one installed instead. ## Components diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index f9a39de..2f79021 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -126,7 +126,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { uint256 amount1In = IERC20(asset1).balanceOf(address(this)); if (amount1In > 0) amount1In = depositAssets(vault1, amount1In) * feeMultiplier / 1e18; - // Verify curve invariant is satisified + // Verify curve invariant is satisfied { uint256 newReserve0 = reserve0 + amount0In - amount0Out; From ccfee9653c0a9112458769d7939ea313c374c280 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 12 Mar 2025 14:13:43 -0400 Subject: [PATCH 219/312] restore correct constructor param --- src/EulerSwapFactory.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index ac6df41..538a715 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -92,7 +92,9 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { address(this), keccak256(abi.encode(address(poolParams.eulerAccount), salt)), keccak256( - abi.encodePacked(type(EulerSwap).creationCode, abi.encode(poolParams, curveParams)) + abi.encodePacked( + type(EulerSwapHook).creationCode, abi.encode(poolManager, poolParams, curveParams) + ) ) ) ) From e30f681a637fe84daf8ee5176d9060e080f3d4d9 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 12 Mar 2025 14:13:58 -0400 Subject: [PATCH 220/312] account for poolManager constructor param --- script/DeployProtocol.s.sol | 4 +++- script/json/DeployProtocol_input.json | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/script/DeployProtocol.s.sol b/script/DeployProtocol.s.sol index ee87fb9..7628f60 100644 --- a/script/DeployProtocol.s.sol +++ b/script/DeployProtocol.s.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.0; import {ScriptUtil} from "./ScriptUtil.s.sol"; import {EulerSwapFactory} from "../src/EulerSwapFactory.sol"; import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; +import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; /// @title Script to deploy EulerSwapFactory & EulerSwapPeriphery. contract DeployProtocol is ScriptUtil { @@ -17,10 +18,11 @@ contract DeployProtocol is ScriptUtil { string memory json = _getJsonFile(inputScriptFileName); address evc = vm.parseJsonAddress(json, ".evc"); + address poolManager = vm.parseJsonAddress(json, ".poolManager"); vm.startBroadcast(deployerAddress); - new EulerSwapFactory(evc); + new EulerSwapFactory(IPoolManager(poolManager), evc); new EulerSwapPeriphery(); vm.stopBroadcast(); diff --git a/script/json/DeployProtocol_input.json b/script/json/DeployProtocol_input.json index 0c26615..fc8cb76 100644 --- a/script/json/DeployProtocol_input.json +++ b/script/json/DeployProtocol_input.json @@ -1,3 +1,4 @@ { - "evc": "0x0C9a3dd6b8F28529d72d7f9cE918D493519EE383" + "evc": "0x0C9a3dd6b8F28529d72d7f9cE918D493519EE383", + "poolManager": "0x000000000004444c5dc75cB358380D2e3dE08A90" } \ No newline at end of file From 4f745c405983c2b4b49de44ed968563d945bd08d Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 12 Mar 2025 15:13:08 -0400 Subject: [PATCH 221/312] wip: setup EulerSwapHook test --- test/EulerSwapHook.swaps.t.sol | 100 +++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 test/EulerSwapHook.swaps.t.sol diff --git a/test/EulerSwapHook.swaps.t.sol b/test/EulerSwapHook.swaps.t.sol new file mode 100644 index 0000000..3261ece --- /dev/null +++ b/test/EulerSwapHook.swaps.t.sol @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; + +import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol"; +import {EulerSwapHook} from "../src/EulerSwapHook.sol"; + +import {IPoolManager, PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol"; +import {PoolSwapTest} from "@uniswap/v4-core/src/test/PoolSwapTest.sol"; +import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; +import {HookMiner} from "v4-periphery/src/utils/HookMiner.sol"; + +contract EulerSwapHookTest is EulerSwapTestBase { + EulerSwap public eulerSwap; + + IPoolManager public poolManager; + PoolSwapTest public swapRouter; + + PoolSwapTest.TestSettings public settings = PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}); + + function setUp() public virtual override { + super.setUp(); + + // TODO: move upstream to EulerSwapTestBase? + poolManager = PoolManagerDeployer.deploy(address(this)); + swapRouter = new PoolSwapTest(poolManager); + + // eulerSwap = createEulerSwap(60e18, 60e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + IEulerSwap.Params memory poolParams = getEulerSwapParams(60e18, 60e18, 0); + IEulerSwap.CurveParams memory curveParams = + IEulerSwap.CurveParams({priceX: 1e18, priceY: 1e18, concentrationX: 0.4e18, concentrationY: 0.85e18}); + bytes memory constructorArgs = abi.encode(poolManager, poolParams, curveParams); + uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG); + (address hookAddress, bytes32 salt) = + HookMiner.find(creator, flags, type(EulerSwapHook).creationCode, constructorArgs); + vm.prank(creator); + eulerSwap = new EulerSwapHook{salt: salt}(poolManager, poolParams, curveParams); + assertEq(address(eulerSwap), hookAddress); + + vm.prank(holder); + evc.setAccountOperator(holder, address(eulerSwap), true); + } + + function test_SwapExactIn() public { + uint256 amountIn = 1e18; + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(periphery), amountIn); + periphery.swapExactIn(address(eulerSwap), address(assetTST), address(assetTST2), amountIn, amountOut); + vm.stopPrank(); + + assertEq(assetTST2.balanceOf(anyone), amountOut); + } + + function test_SwapExactIn_AmountOutLessThanMin() public { + uint256 amountIn = 1e18; + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(periphery), amountIn); + vm.expectRevert(EulerSwapPeriphery.AmountOutLessThanMin.selector); + periphery.swapExactIn(address(eulerSwap), address(assetTST), address(assetTST2), amountIn, amountOut + 1); + vm.stopPrank(); + } + + function test_SwapExactOut() public { + uint256 amountOut = 1e18; + uint256 amountIn = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(periphery), amountIn); + periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut, amountIn); + vm.stopPrank(); + + assertEq(assetTST2.balanceOf(anyone), amountOut); + } + + function test_SwapExactOut_AmountInMoreThanMax() public { + uint256 amountOut = 1e18; + uint256 amountIn = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(periphery), amountIn); + vm.expectRevert(EulerSwapPeriphery.AmountInMoreThanMax.selector); + periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut * 2, amountIn); + vm.stopPrank(); + } +} From 6e31cef3a6a2319f20f22b7dc6f3d85983e070f7 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 12 Mar 2025 15:44:28 -0400 Subject: [PATCH 222/312] assert v4 pool creation --- src/EulerSwapHook.sol | 11 ++++++++--- test/EulerSwapHook.swaps.t.sol | 11 ++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/EulerSwapHook.sol b/src/EulerSwapHook.sol index 1a631ab..f9d06df 100644 --- a/src/EulerSwapHook.sol +++ b/src/EulerSwapHook.sol @@ -16,7 +16,7 @@ import {EulerSwap, IEulerSwap, IEVault} from "./EulerSwap.sol"; contract EulerSwapHook is EulerSwap, BaseHook { using SafeCast for uint256; - PoolKey poolKey; + PoolKey internal _poolKey; constructor(IPoolManager _manager, Params memory params, CurveParams memory curveParams) EulerSwap(params, curveParams) @@ -28,7 +28,7 @@ contract EulerSwapHook is EulerSwap, BaseHook { // convert fee in WAD to pips. 0.003e18 / 1e12 = 3000 = 0.30% uint24 fee = uint24(params.fee / 1e12); - poolKey = PoolKey({ + _poolKey = PoolKey({ currency0: Currency.wrap(asset0Addr), currency1: Currency.wrap(asset1Addr), fee: fee, @@ -37,7 +37,12 @@ contract EulerSwapHook is EulerSwap, BaseHook { }); // create the pool on v4, using starting price as sqrtPrice(1/1) * Q96 - poolManager.initialize(poolKey, 79228162514264337593543950336); + poolManager.initialize(_poolKey, 79228162514264337593543950336); + } + + /// @dev Helper function to return the poolKey as its struct type + function poolKey() external view returns (PoolKey memory) { + return _poolKey; } function _beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata) diff --git a/test/EulerSwapHook.swaps.t.sol b/test/EulerSwapHook.swaps.t.sol index 3261ece..da6dfbd 100644 --- a/test/EulerSwapHook.swaps.t.sol +++ b/test/EulerSwapHook.swaps.t.sol @@ -8,9 +8,13 @@ import {IPoolManager, PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol import {PoolSwapTest} from "@uniswap/v4-core/src/test/PoolSwapTest.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; import {HookMiner} from "v4-periphery/src/utils/HookMiner.sol"; +import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; +import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; contract EulerSwapHookTest is EulerSwapTestBase { - EulerSwap public eulerSwap; + using StateLibrary for IPoolManager; + + EulerSwapHook public eulerSwap; IPoolManager public poolManager; PoolSwapTest public swapRouter; @@ -36,6 +40,11 @@ contract EulerSwapHookTest is EulerSwapTestBase { eulerSwap = new EulerSwapHook{salt: salt}(poolManager, poolParams, curveParams); assertEq(address(eulerSwap), hookAddress); + // confirm pool was created + assertFalse(eulerSwap.poolKey().currency1 == CurrencyLibrary.ADDRESS_ZERO); + (uint160 sqrtPriceX96,,,) = poolManager.getSlot0(eulerSwap.poolKey().toId()); + assertNotEq(sqrtPriceX96, 0); + vm.prank(holder); evc.setAccountOperator(holder, address(eulerSwap), true); } From d103a9f1bb8c9bf820cf5cb7e6800902bff443b5 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 12 Mar 2025 16:07:31 -0400 Subject: [PATCH 223/312] initial test for exact input swap --- test/EulerSwapHook.swaps.t.sol | 78 +++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/test/EulerSwapHook.swaps.t.sol b/test/EulerSwapHook.swaps.t.sol index da6dfbd..0480477 100644 --- a/test/EulerSwapHook.swaps.t.sol +++ b/test/EulerSwapHook.swaps.t.sol @@ -10,6 +10,7 @@ import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; import {HookMiner} from "v4-periphery/src/utils/HookMiner.sol"; import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; +import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; contract EulerSwapHookTest is EulerSwapTestBase { using StateLibrary for IPoolManager; @@ -57,53 +58,60 @@ contract EulerSwapHookTest is EulerSwapTestBase { assetTST.mint(anyone, amountIn); vm.startPrank(anyone); - assetTST.approve(address(periphery), amountIn); - periphery.swapExactIn(address(eulerSwap), address(assetTST), address(assetTST2), amountIn, amountOut); + assetTST.approve(address(swapRouter), amountIn); + + bool zeroForOne = address(assetTST) < address(assetTST2); + IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ + zeroForOne: zeroForOne, + amountSpecified: -int256(amountIn), + sqrtPriceLimitX96: zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1 + }); + swapRouter.swap(eulerSwap.poolKey(), swapParams, settings, ""); vm.stopPrank(); assertEq(assetTST2.balanceOf(anyone), amountOut); } - function test_SwapExactIn_AmountOutLessThanMin() public { - uint256 amountIn = 1e18; - uint256 amountOut = - periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + // function test_SwapExactIn_AmountOutLessThanMin() public { + // uint256 amountIn = 1e18; + // uint256 amountOut = + // periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); - assetTST.mint(anyone, amountIn); + // assetTST.mint(anyone, amountIn); - vm.startPrank(anyone); - assetTST.approve(address(periphery), amountIn); - vm.expectRevert(EulerSwapPeriphery.AmountOutLessThanMin.selector); - periphery.swapExactIn(address(eulerSwap), address(assetTST), address(assetTST2), amountIn, amountOut + 1); - vm.stopPrank(); - } + // vm.startPrank(anyone); + // assetTST.approve(address(periphery), amountIn); + // vm.expectRevert(EulerSwapPeriphery.AmountOutLessThanMin.selector); + // periphery.swapExactIn(address(eulerSwap), address(assetTST), address(assetTST2), amountIn, amountOut + 1); + // vm.stopPrank(); + // } - function test_SwapExactOut() public { - uint256 amountOut = 1e18; - uint256 amountIn = - periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + // function test_SwapExactOut() public { + // uint256 amountOut = 1e18; + // uint256 amountIn = + // periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); - assetTST.mint(anyone, amountIn); + // assetTST.mint(anyone, amountIn); - vm.startPrank(anyone); - assetTST.approve(address(periphery), amountIn); - periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut, amountIn); - vm.stopPrank(); + // vm.startPrank(anyone); + // assetTST.approve(address(periphery), amountIn); + // periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut, amountIn); + // vm.stopPrank(); - assertEq(assetTST2.balanceOf(anyone), amountOut); - } + // assertEq(assetTST2.balanceOf(anyone), amountOut); + // } - function test_SwapExactOut_AmountInMoreThanMax() public { - uint256 amountOut = 1e18; - uint256 amountIn = - periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + // function test_SwapExactOut_AmountInMoreThanMax() public { + // uint256 amountOut = 1e18; + // uint256 amountIn = + // periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); - assetTST.mint(anyone, amountIn); + // assetTST.mint(anyone, amountIn); - vm.startPrank(anyone); - assetTST.approve(address(periphery), amountIn); - vm.expectRevert(EulerSwapPeriphery.AmountInMoreThanMax.selector); - periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut * 2, amountIn); - vm.stopPrank(); - } + // vm.startPrank(anyone); + // assetTST.approve(address(periphery), amountIn); + // vm.expectRevert(EulerSwapPeriphery.AmountInMoreThanMax.selector); + // periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut * 2, amountIn); + // vm.stopPrank(); + // } } From 26ef2a320905b0e7ea757b7a2f70f19b47c23ec4 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Sat, 15 Mar 2025 16:00:38 -0400 Subject: [PATCH 224/312] wip --- test/EulerSwapHook.swaps.t.sol | 41 ++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/test/EulerSwapHook.swaps.t.sol b/test/EulerSwapHook.swaps.t.sol index 0480477..a3445d7 100644 --- a/test/EulerSwapHook.swaps.t.sol +++ b/test/EulerSwapHook.swaps.t.sol @@ -2,8 +2,10 @@ pragma solidity ^0.8.24; import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol"; +import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {EulerSwapHook} from "../src/EulerSwapHook.sol"; +import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {IPoolManager, PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol"; import {PoolSwapTest} from "@uniswap/v4-core/src/test/PoolSwapTest.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; @@ -61,12 +63,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { assetTST.approve(address(swapRouter), amountIn); bool zeroForOne = address(assetTST) < address(assetTST2); - IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ - zeroForOne: zeroForOne, - amountSpecified: -int256(amountIn), - sqrtPriceLimitX96: zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1 - }); - swapRouter.swap(eulerSwap.poolKey(), swapParams, settings, ""); + _swap(eulerSwap.poolKey(), zeroForOne, true, amountIn); vm.stopPrank(); assertEq(assetTST2.balanceOf(anyone), amountOut); @@ -86,20 +83,21 @@ contract EulerSwapHookTest is EulerSwapTestBase { // vm.stopPrank(); // } - // function test_SwapExactOut() public { - // uint256 amountOut = 1e18; - // uint256 amountIn = - // periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + function test_SwapExactOut() public { + uint256 amountOut = 1e18; + uint256 amountIn = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); - // assetTST.mint(anyone, amountIn); + assetTST.mint(anyone, amountIn); - // vm.startPrank(anyone); - // assetTST.approve(address(periphery), amountIn); - // periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut, amountIn); - // vm.stopPrank(); + vm.startPrank(anyone); + assetTST.approve(address(periphery), amountIn); + bool zeroForOne = address(assetTST) < address(assetTST2); + _swap(eulerSwap.poolKey(), zeroForOne, false, amountOut); + vm.stopPrank(); - // assertEq(assetTST2.balanceOf(anyone), amountOut); - // } + assertEq(assetTST2.balanceOf(anyone), amountOut); + } // function test_SwapExactOut_AmountInMoreThanMax() public { // uint256 amountOut = 1e18; @@ -114,4 +112,13 @@ contract EulerSwapHookTest is EulerSwapTestBase { // periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut * 2, amountIn); // vm.stopPrank(); // } + + function _swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount) internal { + IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ + zeroForOne: zeroForOne, + amountSpecified: exactInput ? -int256(amount) : int256(amount), + sqrtPriceLimitX96: zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1 + }); + swapRouter.swap(key, swapParams, settings, ""); + } } From c921f078ade60f0a9aba5d21346cea7c95ca67da Mon Sep 17 00:00:00 2001 From: saucepoint Date: Sat, 15 Mar 2025 16:45:40 -0400 Subject: [PATCH 225/312] delete old test --- test/EulerSwapHook.swaps.t.sol | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/test/EulerSwapHook.swaps.t.sol b/test/EulerSwapHook.swaps.t.sol index a3445d7..b0e3a13 100644 --- a/test/EulerSwapHook.swaps.t.sol +++ b/test/EulerSwapHook.swaps.t.sol @@ -69,20 +69,6 @@ contract EulerSwapHookTest is EulerSwapTestBase { assertEq(assetTST2.balanceOf(anyone), amountOut); } - // function test_SwapExactIn_AmountOutLessThanMin() public { - // uint256 amountIn = 1e18; - // uint256 amountOut = - // periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); - - // assetTST.mint(anyone, amountIn); - - // vm.startPrank(anyone); - // assetTST.approve(address(periphery), amountIn); - // vm.expectRevert(EulerSwapPeriphery.AmountOutLessThanMin.selector); - // periphery.swapExactIn(address(eulerSwap), address(assetTST), address(assetTST2), amountIn, amountOut + 1); - // vm.stopPrank(); - // } - function test_SwapExactOut() public { uint256 amountOut = 1e18; uint256 amountIn = @@ -99,20 +85,6 @@ contract EulerSwapHookTest is EulerSwapTestBase { assertEq(assetTST2.balanceOf(anyone), amountOut); } - // function test_SwapExactOut_AmountInMoreThanMax() public { - // uint256 amountOut = 1e18; - // uint256 amountIn = - // periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); - - // assetTST.mint(anyone, amountIn); - - // vm.startPrank(anyone); - // assetTST.approve(address(periphery), amountIn); - // vm.expectRevert(EulerSwapPeriphery.AmountInMoreThanMax.selector); - // periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut * 2, amountIn); - // vm.stopPrank(); - // } - function _swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount) internal { IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ zeroForOne: zeroForOne, From 43be08e2f8696840e2e19dc95a8bd1e8d8ca2b28 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Sat, 15 Mar 2025 17:08:22 -0400 Subject: [PATCH 226/312] move setup to test base --- test/EulerSwapHook.swaps.t.sol | 18 +---------------- test/EulerSwapTestBase.t.sol | 36 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/test/EulerSwapHook.swaps.t.sol b/test/EulerSwapHook.swaps.t.sol index b0e3a13..036ef6e 100644 --- a/test/EulerSwapHook.swaps.t.sol +++ b/test/EulerSwapHook.swaps.t.sol @@ -8,8 +8,6 @@ import {EulerSwapHook} from "../src/EulerSwapHook.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {IPoolManager, PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol"; import {PoolSwapTest} from "@uniswap/v4-core/src/test/PoolSwapTest.sol"; -import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; -import {HookMiner} from "v4-periphery/src/utils/HookMiner.sol"; import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; @@ -27,29 +25,15 @@ contract EulerSwapHookTest is EulerSwapTestBase { function setUp() public virtual override { super.setUp(); - // TODO: move upstream to EulerSwapTestBase? poolManager = PoolManagerDeployer.deploy(address(this)); swapRouter = new PoolSwapTest(poolManager); - // eulerSwap = createEulerSwap(60e18, 60e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); - IEulerSwap.Params memory poolParams = getEulerSwapParams(60e18, 60e18, 0); - IEulerSwap.CurveParams memory curveParams = - IEulerSwap.CurveParams({priceX: 1e18, priceY: 1e18, concentrationX: 0.4e18, concentrationY: 0.85e18}); - bytes memory constructorArgs = abi.encode(poolManager, poolParams, curveParams); - uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG); - (address hookAddress, bytes32 salt) = - HookMiner.find(creator, flags, type(EulerSwapHook).creationCode, constructorArgs); - vm.prank(creator); - eulerSwap = new EulerSwapHook{salt: salt}(poolManager, poolParams, curveParams); - assertEq(address(eulerSwap), hookAddress); + eulerSwap = createEulerSwapHook(poolManager, 60e18, 60e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); // confirm pool was created assertFalse(eulerSwap.poolKey().currency1 == CurrencyLibrary.ADDRESS_ZERO); (uint160 sqrtPriceX96,,,) = poolManager.getSlot0(eulerSwap.poolKey().toId()); assertNotEq(sqrtPriceX96, 0); - - vm.prank(holder); - evc.setAccountOperator(holder, address(eulerSwap), true); } function test_SwapExactIn() public { diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index 9c2d862..fe5bf5d 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -6,6 +6,10 @@ import {EVaultTestBase, TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.s import {IEVault} from "evk/EVault/IEVault.sol"; import {IEulerSwap, IEVC, EulerSwap} from "../src/EulerSwap.sol"; import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; +import {EulerSwapHook} from "../src/EulerSwapHook.sol"; +import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; +import {HookMiner} from "v4-periphery/src/utils/HookMiner.sol"; +import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; contract EulerSwapTestBase is EVaultTestBase { address public depositor = makeAddr("depositor"); @@ -96,6 +100,38 @@ contract EulerSwapTestBase is EVaultTestBase { return eulerSwap; } + function createEulerSwapHook( + IPoolManager _poolManager, + uint112 debtLimitA, + uint112 debtLimitB, + uint256 fee, + uint256 px, + uint256 py, + uint256 cx, + uint256 cy + ) internal returns (EulerSwapHook) { + IEulerSwap.Params memory poolParams = getEulerSwapParams(debtLimitA, debtLimitB, fee); + IEulerSwap.CurveParams memory curveParams = + IEulerSwap.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}); + + bytes memory constructorArgs = abi.encode(_poolManager, poolParams, curveParams); + (address hookAddress, bytes32 salt) = HookMiner.find( + creator, + uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG), + type(EulerSwapHook).creationCode, + constructorArgs + ); + + vm.prank(creator); + EulerSwapHook eulerSwapHook = new EulerSwapHook{salt: salt}(_poolManager, poolParams, curveParams); + assertEq(address(eulerSwapHook), hookAddress); + + vm.prank(holder); + evc.setAccountOperator(holder, address(eulerSwapHook), true); + + return eulerSwapHook; + } + function mintAndDeposit(address who, IEVault vault, uint256 amount) internal { TestERC20 tok = TestERC20(vault.asset()); tok.mint(who, amount); From e0bfe0e2200b2dda606a43016d2606f3d43e306e Mon Sep 17 00:00:00 2001 From: saucepoint Date: Sat, 15 Mar 2025 17:09:37 -0400 Subject: [PATCH 227/312] increase assertions --- test/EulerSwapHook.swaps.t.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/EulerSwapHook.swaps.t.sol b/test/EulerSwapHook.swaps.t.sol index 036ef6e..9522533 100644 --- a/test/EulerSwapHook.swaps.t.sol +++ b/test/EulerSwapHook.swaps.t.sol @@ -50,6 +50,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { _swap(eulerSwap.poolKey(), zeroForOne, true, amountIn); vm.stopPrank(); + assertEq(assetTST.balanceOf(anyone), 0); assertEq(assetTST2.balanceOf(anyone), amountOut); } @@ -66,6 +67,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { _swap(eulerSwap.poolKey(), zeroForOne, false, amountOut); vm.stopPrank(); + assertEq(assetTST.balanceOf(anyone), 0); assertEq(assetTST2.balanceOf(anyone), amountOut); } From bca991e9a377a8f2815230c435c7cb6dac720c89 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 18 Mar 2025 06:53:21 -0400 Subject: [PATCH 228/312] inline computeQuote from periphery --- src/EulerSwapHook.sol | 215 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) diff --git a/src/EulerSwapHook.sol b/src/EulerSwapHook.sol index f9d06df..8425298 100644 --- a/src/EulerSwapHook.sol +++ b/src/EulerSwapHook.sol @@ -100,4 +100,219 @@ contract EulerSwapHook is EulerSwap, BaseHook { // TODO: fix salt mining & verification for the hook function getHookPermissions() public pure override returns (Hooks.Permissions memory) {} function validateHookAddress(BaseHook) internal pure override {} + + + + + + + + + + /// @dev Computes the quote for a swap by applying fees and validating state conditions + /// @param eulerSwap The EulerSwap contract to quote from + /// @param tokenIn The input token address + /// @param tokenOut The output token address + /// @param amount The amount to quote (input amount if exactIn=true, output amount if exactIn=false) + /// @param exactIn True if quoting for exact input amount, false if quoting for exact output amount + /// @return The quoted amount (output amount if exactIn=true, input amount if exactIn=false) + /// @dev Validates: + /// - EulerSwap operator is installed + /// - Token pair is supported + /// - Sufficient reserves exist + /// - Sufficient cash is available + function computeQuote(IEulerSwap eulerSwap, address tokenIn, address tokenOut, uint256 amount, bool exactIn) + internal + view + returns (uint256) + { + require( + IEVC(eulerSwap.EVC()).isAccountOperatorAuthorized(eulerSwap.eulerAccount(), address(eulerSwap)), + OperatorNotInstalled() + ); + require(amount <= type(uint112).max, SwapLimitExceeded()); + + uint256 feeMultiplier = eulerSwap.feeMultiplier(); + (uint112 reserve0, uint112 reserve1,) = eulerSwap.getReserves(); + + // exactIn: decrease received amountIn, rounding down + if (exactIn) amount = amount * feeMultiplier / 1e18; + + bool asset0IsInput = checkTokens(eulerSwap, tokenIn, tokenOut); + (uint256 inLimit, uint256 outLimit) = calcLimits(eulerSwap, asset0IsInput); + + uint256 quote = binarySearch(eulerSwap, reserve0, reserve1, amount, exactIn, asset0IsInput); + + if (exactIn) { + // if `exactIn`, `quote` is the amount of assets to buy from the AMM + require(amount <= inLimit && quote <= outLimit, SwapLimitExceeded()); + } else { + // if `!exactIn`, `amount` is the amount of assets to buy from the AMM + require(amount <= outLimit && quote <= inLimit, SwapLimitExceeded()); + } + + // exactOut: increase required quote(amountIn), rounding up + if (!exactIn) quote = (quote * 1e18 + (feeMultiplier - 1)) / feeMultiplier; + + return quote; + } + + /// @notice Binary searches for the output amount along a swap curve given input parameters + /// @dev General-purpose routine for binary searching swapping curves. + /// Although some curves may have more efficient closed-form solutions, + /// this works with any monotonic curve. + /// @param eulerSwap The EulerSwap contract to search the curve for + /// @param reserve0 Current reserve of asset0 in the pool + /// @param reserve1 Current reserve of asset1 in the pool + /// @param amount The input or output amount depending on exactIn + /// @param exactIn True if amount is input amount, false if amount is output amount + /// @param asset0IsInput True if asset0 is being input, false if asset1 is being input + /// @return output The calculated output amount from the binary search + function binarySearch( + IEulerSwap eulerSwap, + uint112 reserve0, + uint112 reserve1, + uint256 amount, + bool exactIn, + bool asset0IsInput + ) internal view returns (uint256 output) { + int256 dx; + int256 dy; + + if (exactIn) { + if (asset0IsInput) dx = int256(amount); + else dy = int256(amount); + } else { + if (asset0IsInput) dy = -int256(amount); + else dx = -int256(amount); + } + + unchecked { + int256 reserve0New = int256(uint256(reserve0)) + dx; + int256 reserve1New = int256(uint256(reserve1)) + dy; + require(reserve0New > 0 && reserve1New > 0, SwapLimitExceeded()); + + uint256 low; + uint256 high = type(uint112).max; + + while (low < high) { + uint256 mid = (low + high) / 2; + require(mid > 0, SwapLimitExceeded()); + (uint256 a, uint256 b) = dy == 0 ? (uint256(reserve0New), mid) : (mid, uint256(reserve1New)); + if (eulerSwap.verify(a, b)) { + high = mid; + } else { + low = mid + 1; + } + } + + require(high < type(uint112).max, SwapLimitExceeded()); // at least one point verified + + if (dx != 0) dy = int256(low) - reserve1New; + else dx = int256(low) - reserve0New; + } + + if (exactIn) { + if (asset0IsInput) output = uint256(-dy); + else output = uint256(-dx); + } else { + if (asset0IsInput) output = dx >= 0 ? uint256(dx) : 0; + else output = dy >= 0 ? uint256(dy) : 0; + } + } + + /** + * @notice Calculates the maximum input and output amounts for a swap based on protocol constraints + * @dev Determines limits by checking multiple factors: + * 1. Supply caps and existing debt for the input token + * 2. Available reserves in the EulerSwap for the output token + * 3. Available cash and borrow caps for the output token + * 4. Account balances in the respective vaults + * + * @param es The EulerSwap contract to calculate limits for + * @param asset0IsInput Boolean indicating whether asset0 (true) or asset1 (false) is the input token + * @return uint256 Maximum amount of input token that can be deposited + * @return uint256 Maximum amount of output token that can be withdrawn + */ + function calcLimits(IEulerSwap es, bool asset0IsInput) internal view returns (uint256, uint256) { + uint256 inLimit = type(uint112).max; + uint256 outLimit = type(uint112).max; + + address eulerAccount = es.eulerAccount(); + (IEVault vault0, IEVault vault1) = (IEVault(es.vault0()), IEVault(es.vault1())); + // Supply caps on input + { + IEVault vault = (asset0IsInput ? vault0 : vault1); + uint256 maxDeposit = vault.debtOf(eulerAccount) + vault.maxDeposit(eulerAccount); + if (maxDeposit < inLimit) inLimit = maxDeposit; + } + + // Remaining reserves of output + { + (uint112 reserve0, uint112 reserve1,) = es.getReserves(); + uint112 reserveLimit = asset0IsInput ? reserve1 : reserve0; + if (reserveLimit < outLimit) outLimit = reserveLimit; + } + + // Remaining cash and borrow caps in output + { + IEVault vault = (asset0IsInput ? vault1 : vault0); + + uint256 cash = vault.cash(); + if (cash < outLimit) outLimit = cash; + + (, uint16 borrowCap) = vault.caps(); + uint256 maxWithdraw = decodeCap(uint256(borrowCap)); + maxWithdraw = vault.totalBorrows() > maxWithdraw ? 0 : maxWithdraw - vault.totalBorrows(); + if (maxWithdraw > cash) maxWithdraw = cash; + maxWithdraw += vault.convertToAssets(vault.balanceOf(eulerAccount)); + if (maxWithdraw < outLimit) outLimit = maxWithdraw; + } + + return (inLimit, outLimit); + } + + /** + * @notice Decodes a compact-format cap value to its actual numerical value + * @dev The cap uses a compact-format where: + * - If amountCap == 0, there's no cap (returns max uint256) + * - Otherwise, the lower 6 bits represent the exponent (10^exp) + * - The upper bits (>> 6) represent the mantissa + * - The formula is: (10^exponent * mantissa) / 100 + * @param amountCap The compact-format cap value to decode + * @return The actual numerical cap value (type(uint256).max if uncapped) + * @custom:security Uses unchecked math for gas optimization as calculations cannot overflow: + * maximum possible value 10^(2^6-1) * (2^10-1) ≈ 1.023e+66 < 2^256 + */ + function decodeCap(uint256 amountCap) internal pure returns (uint256) { + if (amountCap == 0) return type(uint256).max; + + unchecked { + // Cannot overflow because this is less than 2**256: + // 10**(2**6 - 1) * (2**10 - 1) = 1.023e+66 + return 10 ** (amountCap & 63) * (amountCap >> 6) / 100; + } + } + + /** + * @notice Verifies that the given tokens are supported by the EulerSwap pool and determines swap direction + * @dev Returns a boolean indicating whether the input token is asset0 (true) or asset1 (false) + * @param eulerSwap The EulerSwap pool contract to check against + * @param tokenIn The input token address for the swap + * @param tokenOut The output token address for the swap + * @return asset0IsInput True if tokenIn is asset0 and tokenOut is asset1, false if reversed + * @custom:error UnsupportedPair Thrown if the token pair is not supported by the EulerSwap pool + */ + function checkTokens(IEulerSwap eulerSwap, address tokenIn, address tokenOut) + internal + view + returns (bool asset0IsInput) + { + address asset0 = eulerSwap.asset0(); + address asset1 = eulerSwap.asset1(); + + if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true; + else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; + else revert UnsupportedPair(); + } } From 9b6bd10af654dbdce7fe992402bd97e295402fed Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 18 Mar 2025 07:25:37 -0400 Subject: [PATCH 229/312] use computeQuote to get amountIn/amountOut --- src/EulerSwapHook.sol | 112 ++++++++---------------------------------- 1 file changed, 21 insertions(+), 91 deletions(-) diff --git a/src/EulerSwapHook.sol b/src/EulerSwapHook.sol index 8425298..f4b97b5 100644 --- a/src/EulerSwapHook.sol +++ b/src/EulerSwapHook.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; +import {console} from "forge-std/Test.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {BaseHook} from "v4-periphery/src/utils/BaseHook.sol"; import {PoolKey} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; @@ -55,11 +56,19 @@ contract EulerSwapHook is EulerSwap, BaseHook { params.zeroForOne ? (key.currency0, key.currency1) : (key.currency1, key.currency0); bool isExactInput = params.amountSpecified < 0; - // TODO: compute the open side of the trade, using computeQuote() ? uint256 amountIn; uint256 amountOut; - // uint256 amountIn = isExactInput ? uint256(-params.amountSpecified) : computeQuote(..., false); - // uint256 amountOut = isExactInput ? computeQuote(..., true) : uint256(params.amountSpecified); + + if (isExactInput) { + amountIn = uint256(-params.amountSpecified); + amountOut = computeQuote(params.zeroForOne, uint256(-params.amountSpecified), true); + } else { + amountIn = computeQuote(params.zeroForOne, uint256(params.amountSpecified), false); + amountOut = uint256(params.amountSpecified); + } + + console.log("amountIn", amountIn); + console.log("amountOut", amountOut); // take the input token, from the PoolManager to the Euler vault // the debt will be paid by the swapper via the swap router @@ -106,42 +115,26 @@ contract EulerSwapHook is EulerSwap, BaseHook { + error SwapLimitExceeded(); + error OperatorNotInstalled(); - - - /// @dev Computes the quote for a swap by applying fees and validating state conditions - /// @param eulerSwap The EulerSwap contract to quote from - /// @param tokenIn The input token address - /// @param tokenOut The output token address - /// @param amount The amount to quote (input amount if exactIn=true, output amount if exactIn=false) - /// @param exactIn True if quoting for exact input amount, false if quoting for exact output amount - /// @return The quoted amount (output amount if exactIn=true, input amount if exactIn=false) - /// @dev Validates: - /// - EulerSwap operator is installed - /// - Token pair is supported - /// - Sufficient reserves exist - /// - Sufficient cash is available - function computeQuote(IEulerSwap eulerSwap, address tokenIn, address tokenOut, uint256 amount, bool exactIn) + function computeQuote(bool asset0IsInput, uint256 amount, bool exactIn) internal view returns (uint256) { require( - IEVC(eulerSwap.EVC()).isAccountOperatorAuthorized(eulerSwap.eulerAccount(), address(eulerSwap)), + evc.isAccountOperatorAuthorized(eulerAccount, address(this)), OperatorNotInstalled() ); require(amount <= type(uint112).max, SwapLimitExceeded()); - uint256 feeMultiplier = eulerSwap.feeMultiplier(); - (uint112 reserve0, uint112 reserve1,) = eulerSwap.getReserves(); - // exactIn: decrease received amountIn, rounding down if (exactIn) amount = amount * feeMultiplier / 1e18; - bool asset0IsInput = checkTokens(eulerSwap, tokenIn, tokenOut); - (uint256 inLimit, uint256 outLimit) = calcLimits(eulerSwap, asset0IsInput); + (uint256 inLimit, uint256 outLimit) = calcLimits(asset0IsInput); - uint256 quote = binarySearch(eulerSwap, reserve0, reserve1, amount, exactIn, asset0IsInput); + uint256 quote = binarySearch(amount, exactIn, asset0IsInput); if (exactIn) { // if `exactIn`, `quote` is the amount of assets to buy from the AMM @@ -157,21 +150,7 @@ contract EulerSwapHook is EulerSwap, BaseHook { return quote; } - /// @notice Binary searches for the output amount along a swap curve given input parameters - /// @dev General-purpose routine for binary searching swapping curves. - /// Although some curves may have more efficient closed-form solutions, - /// this works with any monotonic curve. - /// @param eulerSwap The EulerSwap contract to search the curve for - /// @param reserve0 Current reserve of asset0 in the pool - /// @param reserve1 Current reserve of asset1 in the pool - /// @param amount The input or output amount depending on exactIn - /// @param exactIn True if amount is input amount, false if amount is output amount - /// @param asset0IsInput True if asset0 is being input, false if asset1 is being input - /// @return output The calculated output amount from the binary search function binarySearch( - IEulerSwap eulerSwap, - uint112 reserve0, - uint112 reserve1, uint256 amount, bool exactIn, bool asset0IsInput @@ -199,7 +178,7 @@ contract EulerSwapHook is EulerSwap, BaseHook { uint256 mid = (low + high) / 2; require(mid > 0, SwapLimitExceeded()); (uint256 a, uint256 b) = dy == 0 ? (uint256(reserve0New), mid) : (mid, uint256(reserve1New)); - if (eulerSwap.verify(a, b)) { + if (verify(a, b)) { high = mid; } else { low = mid + 1; @@ -221,25 +200,11 @@ contract EulerSwapHook is EulerSwap, BaseHook { } } - /** - * @notice Calculates the maximum input and output amounts for a swap based on protocol constraints - * @dev Determines limits by checking multiple factors: - * 1. Supply caps and existing debt for the input token - * 2. Available reserves in the EulerSwap for the output token - * 3. Available cash and borrow caps for the output token - * 4. Account balances in the respective vaults - * - * @param es The EulerSwap contract to calculate limits for - * @param asset0IsInput Boolean indicating whether asset0 (true) or asset1 (false) is the input token - * @return uint256 Maximum amount of input token that can be deposited - * @return uint256 Maximum amount of output token that can be withdrawn - */ - function calcLimits(IEulerSwap es, bool asset0IsInput) internal view returns (uint256, uint256) { + function calcLimits(bool asset0IsInput) internal view returns (uint256, uint256) { uint256 inLimit = type(uint112).max; uint256 outLimit = type(uint112).max; - address eulerAccount = es.eulerAccount(); - (IEVault vault0, IEVault vault1) = (IEVault(es.vault0()), IEVault(es.vault1())); + (IEVault vault0, IEVault vault1) = (IEVault(vault0), IEVault(vault1)); // Supply caps on input { IEVault vault = (asset0IsInput ? vault0 : vault1); @@ -249,7 +214,6 @@ contract EulerSwapHook is EulerSwap, BaseHook { // Remaining reserves of output { - (uint112 reserve0, uint112 reserve1,) = es.getReserves(); uint112 reserveLimit = asset0IsInput ? reserve1 : reserve0; if (reserveLimit < outLimit) outLimit = reserveLimit; } @@ -272,18 +236,6 @@ contract EulerSwapHook is EulerSwap, BaseHook { return (inLimit, outLimit); } - /** - * @notice Decodes a compact-format cap value to its actual numerical value - * @dev The cap uses a compact-format where: - * - If amountCap == 0, there's no cap (returns max uint256) - * - Otherwise, the lower 6 bits represent the exponent (10^exp) - * - The upper bits (>> 6) represent the mantissa - * - The formula is: (10^exponent * mantissa) / 100 - * @param amountCap The compact-format cap value to decode - * @return The actual numerical cap value (type(uint256).max if uncapped) - * @custom:security Uses unchecked math for gas optimization as calculations cannot overflow: - * maximum possible value 10^(2^6-1) * (2^10-1) ≈ 1.023e+66 < 2^256 - */ function decodeCap(uint256 amountCap) internal pure returns (uint256) { if (amountCap == 0) return type(uint256).max; @@ -293,26 +245,4 @@ contract EulerSwapHook is EulerSwap, BaseHook { return 10 ** (amountCap & 63) * (amountCap >> 6) / 100; } } - - /** - * @notice Verifies that the given tokens are supported by the EulerSwap pool and determines swap direction - * @dev Returns a boolean indicating whether the input token is asset0 (true) or asset1 (false) - * @param eulerSwap The EulerSwap pool contract to check against - * @param tokenIn The input token address for the swap - * @param tokenOut The output token address for the swap - * @return asset0IsInput True if tokenIn is asset0 and tokenOut is asset1, false if reversed - * @custom:error UnsupportedPair Thrown if the token pair is not supported by the EulerSwap pool - */ - function checkTokens(IEulerSwap eulerSwap, address tokenIn, address tokenOut) - internal - view - returns (bool asset0IsInput) - { - address asset0 = eulerSwap.asset0(); - address asset1 = eulerSwap.asset1(); - - if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true; - else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; - else revert UnsupportedPair(); - } } From 0989f17b8fda47a4a8d3e06e1279a3d25d1151ab Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 18 Mar 2025 13:46:27 -0400 Subject: [PATCH 230/312] clean-up --- src/EulerSwapHook.sol | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/EulerSwapHook.sol b/src/EulerSwapHook.sol index f4b97b5..7254735 100644 --- a/src/EulerSwapHook.sol +++ b/src/EulerSwapHook.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; -import {console} from "forge-std/Test.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {BaseHook} from "v4-periphery/src/utils/BaseHook.sol"; import {PoolKey} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; @@ -67,9 +66,6 @@ contract EulerSwapHook is EulerSwap, BaseHook { amountOut = uint256(params.amountSpecified); } - console.log("amountIn", amountIn); - console.log("amountOut", amountOut); - // take the input token, from the PoolManager to the Euler vault // the debt will be paid by the swapper via the swap router // TODO: can we optimize the transfer by pulling from PoolManager directly to Euler? From 79b7d26199a92baa91e016a01a7decc60d36fb80 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 18 Mar 2025 13:46:43 -0400 Subject: [PATCH 231/312] testing fixes - eulerSwap instance should be activated first for approvals/enabling collateral - used to be done on first swap - Seeds poolManager with starting balance - Typo in exact output test --- test/EulerSwapHook.swaps.t.sol | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/EulerSwapHook.swaps.t.sol b/test/EulerSwapHook.swaps.t.sol index 9522533..7b8fb20 100644 --- a/test/EulerSwapHook.swaps.t.sol +++ b/test/EulerSwapHook.swaps.t.sol @@ -29,11 +29,16 @@ contract EulerSwapHookTest is EulerSwapTestBase { swapRouter = new PoolSwapTest(poolManager); eulerSwap = createEulerSwapHook(poolManager, 60e18, 60e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); + eulerSwap.activate(); // confirm pool was created assertFalse(eulerSwap.poolKey().currency1 == CurrencyLibrary.ADDRESS_ZERO); (uint160 sqrtPriceX96,,,) = poolManager.getSlot0(eulerSwap.poolKey().toId()); assertNotEq(sqrtPriceX96, 0); + + // Seed the poolManager with balance so that transient withdrawing before depositing succeeds + assetTST.mint(address(poolManager), 1000e18); + assetTST2.mint(address(poolManager), 1000e18); } function test_SwapExactIn() public { @@ -62,7 +67,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { assetTST.mint(anyone, amountIn); vm.startPrank(anyone); - assetTST.approve(address(periphery), amountIn); + assetTST.approve(address(swapRouter), amountIn); bool zeroForOne = address(assetTST) < address(assetTST2); _swap(eulerSwap.poolKey(), zeroForOne, false, amountOut); vm.stopPrank(); From 47664543f81a2a7bc299a4e84ade8364ec07980f Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 18 Mar 2025 13:51:11 -0400 Subject: [PATCH 232/312] fmt --- src/EulerSwapHook.sol | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/src/EulerSwapHook.sol b/src/EulerSwapHook.sol index 7254735..c4b8567 100644 --- a/src/EulerSwapHook.sol +++ b/src/EulerSwapHook.sol @@ -106,23 +106,11 @@ contract EulerSwapHook is EulerSwap, BaseHook { function getHookPermissions() public pure override returns (Hooks.Permissions memory) {} function validateHookAddress(BaseHook) internal pure override {} - - - - - error SwapLimitExceeded(); error OperatorNotInstalled(); - function computeQuote(bool asset0IsInput, uint256 amount, bool exactIn) - internal - view - returns (uint256) - { - require( - evc.isAccountOperatorAuthorized(eulerAccount, address(this)), - OperatorNotInstalled() - ); + function computeQuote(bool asset0IsInput, uint256 amount, bool exactIn) internal view returns (uint256) { + require(evc.isAccountOperatorAuthorized(eulerAccount, address(this)), OperatorNotInstalled()); require(amount <= type(uint112).max, SwapLimitExceeded()); // exactIn: decrease received amountIn, rounding down @@ -146,11 +134,7 @@ contract EulerSwapHook is EulerSwap, BaseHook { return quote; } - function binarySearch( - uint256 amount, - bool exactIn, - bool asset0IsInput - ) internal view returns (uint256 output) { + function binarySearch(uint256 amount, bool exactIn, bool asset0IsInput) internal view returns (uint256 output) { int256 dx; int256 dy; From 95e473fc1e4b9f002740c2f39e2610e8696d81f4 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Fri, 21 Mar 2025 17:28:23 -0400 Subject: [PATCH 233/312] verify that prepaid input does not have token liquidity issues --- test/EulerSwapHook.swaps.t.sol | 26 +++++++++++-- test/utils/MinimalRouter.sol | 70 ++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 test/utils/MinimalRouter.sol diff --git a/test/EulerSwapHook.swaps.t.sol b/test/EulerSwapHook.swaps.t.sol index 7b8fb20..53977ce 100644 --- a/test/EulerSwapHook.swaps.t.sol +++ b/test/EulerSwapHook.swaps.t.sol @@ -8,6 +8,7 @@ import {EulerSwapHook} from "../src/EulerSwapHook.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {IPoolManager, PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol"; import {PoolSwapTest} from "@uniswap/v4-core/src/test/PoolSwapTest.sol"; +import {MinimalRouter} from "./utils/MinimalRouter.sol"; import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; @@ -19,6 +20,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { IPoolManager public poolManager; PoolSwapTest public swapRouter; + MinimalRouter public minimalRouter; PoolSwapTest.TestSettings public settings = PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}); @@ -27,6 +29,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { poolManager = PoolManagerDeployer.deploy(address(this)); swapRouter = new PoolSwapTest(poolManager); + minimalRouter = new MinimalRouter(poolManager); eulerSwap = createEulerSwapHook(poolManager, 60e18, 60e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); eulerSwap.activate(); @@ -42,23 +45,40 @@ contract EulerSwapHookTest is EulerSwapTestBase { } function test_SwapExactIn() public { - uint256 amountIn = 1e18; + uint256 amountIn = 1001e18; uint256 amountOut = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); assetTST.mint(anyone, amountIn); vm.startPrank(anyone); - assetTST.approve(address(swapRouter), amountIn); + assetTST.approve(address(minimalRouter), amountIn); bool zeroForOne = address(assetTST) < address(assetTST2); - _swap(eulerSwap.poolKey(), zeroForOne, true, amountIn); + minimalRouter.swap(eulerSwap.poolKey(), zeroForOne, true, amountIn, ""); vm.stopPrank(); assertEq(assetTST.balanceOf(anyone), 0); assertEq(assetTST2.balanceOf(anyone), amountOut); } + /// @dev swapping with an amount that exceeds PoolManager's ERC20 token balance will revert + /// if the router does not pre-pay the input + function test_swapExactIn_revertWithoutTokenLiquidity() public { + uint256 amountIn = 1001e18; // input amount exceeds + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(swapRouter), amountIn); + + bool zeroForOne = address(assetTST) < address(assetTST2); + PoolKey memory poolKey = eulerSwap.poolKey(); + vm.expectRevert(); + _swap(poolKey, zeroForOne, true, amountIn); + vm.stopPrank(); + } + function test_SwapExactOut() public { uint256 amountOut = 1e18; uint256 amountIn = diff --git a/test/utils/MinimalRouter.sol b/test/utils/MinimalRouter.sol new file mode 100644 index 0000000..e667adb --- /dev/null +++ b/test/utils/MinimalRouter.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.24; + +import {CurrencyLibrary, Currency} from "@uniswap/v4-core/src/types/Currency.sol"; +import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; +import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; +import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; +import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; +import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; +import {CurrencySettler} from "@uniswap/v4-core/test/utils/CurrencySettler.sol"; +import {SafeCallback} from "v4-periphery/src/base/SafeCallback.sol"; +import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; + +contract MinimalRouter is SafeCallback { + using CurrencySettler for Currency; + + uint160 public constant MIN_PRICE_LIMIT = TickMath.MIN_SQRT_PRICE + 1; + uint160 public constant MAX_PRICE_LIMIT = TickMath.MAX_SQRT_PRICE - 1; + + constructor(IPoolManager _manager) SafeCallback(_manager) {} + + function swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount, bytes memory hookData) + external + payable + returns (BalanceDelta delta) + { + delta = abi.decode( + poolManager.unlock(abi.encode(msg.sender, key, zeroForOne, exactInput, amount, hookData)), (BalanceDelta) + ); + + uint256 ethBalance = address(this).balance; + if (ethBalance > 0) CurrencyLibrary.ADDRESS_ZERO.transfer(msg.sender, ethBalance); + } + + function _unlockCallback(bytes calldata data) internal override returns (bytes memory) { + (address sender, PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount, bytes memory hookData) = + abi.decode(data, (address, PoolKey, bool, bool, uint256, bytes)); + + // for exact input swaps, send the input first to avoid PoolManager token balance issues + if (exactInput) { + zeroForOne + ? key.currency0.settle(poolManager, sender, amount, false) + : key.currency1.settle(poolManager, sender, amount, false); + } + + BalanceDelta delta = poolManager.swap( + key, + IPoolManager.SwapParams({ + zeroForOne: zeroForOne, + amountSpecified: exactInput ? -int256(amount) : int256(amount), + sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT + }), + hookData + ); + + if (!exactInput && delta.amount0() < 0) { + key.currency0.settle(poolManager, sender, uint256(int256(-delta.amount0())), false); + } else if (delta.amount0() > 0) { + key.currency0.take(poolManager, sender, uint256(int256(delta.amount0())), false); + } + + if (!exactInput && delta.amount1() < 0) { + key.currency1.settle(poolManager, sender, uint256(int256(-delta.amount1())), false); + } else if (delta.amount1() > 0) { + key.currency1.take(poolManager, sender, uint256(int256(delta.amount1())), false); + } + + return abi.encode(delta); + } +} From 62bdbcea41d8a0e57bde9084ee4967e68d6b49d9 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 21 Mar 2025 17:48:32 -0400 Subject: [PATCH 234/312] fix for when controller enabled but debt is 0 --- src/EulerSwap.sol | 14 ++++++-------- test/DepositFailures.t.sol | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 2f79021..d3e8cb4 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -219,17 +219,15 @@ contract EulerSwap is IEulerSwap, EVCUtil { /// @dev After successful deposit, if the user has any outstanding controller-enabled debt, it attempts to repay it. /// @dev If all debt is repaid, the controller is automatically disabled to reduce gas costs in future operations. function depositAssets(address vault, uint256 amount) internal returns (uint256) { - uint256 debt = myDebt(vault); uint256 deposited; - if (debt > 0) { - uint256 repayAmount = amount > debt ? debt : amount; + if (IEVC(evc).isControllerEnabled(eulerAccount, vault)) { + uint256 debt = myDebt(vault); + uint256 repaid = IEVault(vault).repay(amount > debt ? debt : amount, eulerAccount); - IEVault(vault).repay(repayAmount, eulerAccount); - - amount -= repayAmount; - debt -= repayAmount; - deposited += repayAmount; + amount -= repaid; + debt -= repaid; + deposited += repaid; if (debt == 0) { IEVC(evc).call(vault, eulerAccount, 0, abi.encodeCall(IRiskManager.disableController, ())); diff --git a/test/DepositFailures.t.sol b/test/DepositFailures.t.sol index a0f93ed..a3f6290 100644 --- a/test/DepositFailures.t.sol +++ b/test/DepositFailures.t.sol @@ -85,4 +85,26 @@ contract DepositFailuresTest is EulerSwapTestBase { assertEq(assetTST2.balanceOf(address(eulerSwap)), 1); // griefing transfer was untouched } + + function test_manualEnableController() public monotonicHolderNAV { + vm.prank(holder); + evc.enableController(holder, address(eTST)); + + uint256 amountIn = 50e18; + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + + assetTST.mint(address(this), amountIn); + assetTST.transfer(address(eulerSwap), amountIn); + eulerSwap.swap(0, amountOut, address(this), ""); + + // Swap the other way to measure gas impact + + amountIn = 100e18; + amountOut = periphery.quoteExactInput(address(eulerSwap), address(assetTST2), address(assetTST), amountIn); + + assetTST2.mint(address(this), amountIn); + assetTST2.transfer(address(eulerSwap), amountIn); + eulerSwap.swap(amountOut, 0, address(this), ""); + } } From 68197e0d15ac0b80f527c58818193ab049c5b7d1 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Mon, 24 Mar 2025 12:51:10 -0400 Subject: [PATCH 235/312] reworked router to prepay input --- test/EulerSwapHook.swaps.t.sol | 40 +++++++++++++++----- test/utils/MinimalRouter.sol | 67 +++++++++++++++++++++++----------- 2 files changed, 76 insertions(+), 31 deletions(-) diff --git a/test/EulerSwapHook.swaps.t.sol b/test/EulerSwapHook.swaps.t.sol index 53977ce..2cd8ad8 100644 --- a/test/EulerSwapHook.swaps.t.sol +++ b/test/EulerSwapHook.swaps.t.sol @@ -12,6 +12,7 @@ import {MinimalRouter} from "./utils/MinimalRouter.sol"; import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; +import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; contract EulerSwapHookTest is EulerSwapTestBase { using StateLibrary for IPoolManager; @@ -38,14 +39,10 @@ contract EulerSwapHookTest is EulerSwapTestBase { assertFalse(eulerSwap.poolKey().currency1 == CurrencyLibrary.ADDRESS_ZERO); (uint160 sqrtPriceX96,,,) = poolManager.getSlot0(eulerSwap.poolKey().toId()); assertNotEq(sqrtPriceX96, 0); - - // Seed the poolManager with balance so that transient withdrawing before depositing succeeds - assetTST.mint(address(poolManager), 1000e18); - assetTST2.mint(address(poolManager), 1000e18); } function test_SwapExactIn() public { - uint256 amountIn = 1001e18; + uint256 amountIn = 1e18; uint256 amountOut = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); @@ -55,17 +52,20 @@ contract EulerSwapHookTest is EulerSwapTestBase { assetTST.approve(address(minimalRouter), amountIn); bool zeroForOne = address(assetTST) < address(assetTST2); - minimalRouter.swap(eulerSwap.poolKey(), zeroForOne, true, amountIn, ""); + BalanceDelta result = minimalRouter.swap(eulerSwap.poolKey(), zeroForOne, amountIn, 0, ""); vm.stopPrank(); assertEq(assetTST.balanceOf(anyone), 0); assertEq(assetTST2.balanceOf(anyone), amountOut); + + assertEq(zeroForOne ? uint256(-int256(result.amount0())) : uint256(-int256(result.amount1())), amountIn); + assertEq(zeroForOne ? uint256(int256(result.amount1())) : uint256(int256(result.amount0())), amountOut); } /// @dev swapping with an amount that exceeds PoolManager's ERC20 token balance will revert /// if the router does not pre-pay the input function test_swapExactIn_revertWithoutTokenLiquidity() public { - uint256 amountIn = 1001e18; // input amount exceeds + uint256 amountIn = 1e18; // input amount exceeds PoolManager balance assetTST.mint(anyone, amountIn); @@ -87,13 +87,35 @@ contract EulerSwapHookTest is EulerSwapTestBase { assetTST.mint(anyone, amountIn); vm.startPrank(anyone); - assetTST.approve(address(swapRouter), amountIn); + assetTST.approve(address(minimalRouter), amountIn); + bool zeroForOne = address(assetTST) < address(assetTST2); - _swap(eulerSwap.poolKey(), zeroForOne, false, amountOut); + BalanceDelta result = minimalRouter.swap(eulerSwap.poolKey(), zeroForOne, amountIn, amountOut, ""); vm.stopPrank(); assertEq(assetTST.balanceOf(anyone), 0); assertEq(assetTST2.balanceOf(anyone), amountOut); + + assertEq(zeroForOne ? uint256(-int256(result.amount0())) : uint256(-int256(result.amount1())), amountIn); + assertEq(zeroForOne ? uint256(int256(result.amount1())) : uint256(int256(result.amount0())), amountOut); + } + + /// @dev swapping with an amount that exceeds PoolManager's ERC20 token balance will revert + /// if the router does not pre-pay the input + function test_SwapExactOut_revertWithoutTokenLiquidity() public { + uint256 amountOut = 1e18; + uint256 amountIn = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(swapRouter), amountIn); + bool zeroForOne = address(assetTST) < address(assetTST2); + PoolKey memory poolKey = eulerSwap.poolKey(); + vm.expectRevert(); + _swap(poolKey, zeroForOne, false, amountOut); + vm.stopPrank(); } function _swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount) internal { diff --git a/test/utils/MinimalRouter.sol b/test/utils/MinimalRouter.sol index e667adb..bab8408 100644 --- a/test/utils/MinimalRouter.sol +++ b/test/utils/MinimalRouter.sol @@ -3,15 +3,17 @@ pragma solidity ^0.8.24; import {CurrencyLibrary, Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; +import {BalanceDelta, toBalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; import {CurrencySettler} from "@uniswap/v4-core/test/utils/CurrencySettler.sol"; import {SafeCallback} from "v4-periphery/src/base/SafeCallback.sol"; import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; +import {TransientStateLibrary} from "@uniswap/v4-core/src/libraries/TransientStateLibrary.sol"; contract MinimalRouter is SafeCallback { + using TransientStateLibrary for IPoolManager; using CurrencySettler for Currency; uint160 public constant MIN_PRICE_LIMIT = TickMath.MIN_SQRT_PRICE + 1; @@ -19,13 +21,19 @@ contract MinimalRouter is SafeCallback { constructor(IPoolManager _manager) SafeCallback(_manager) {} - function swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount, bytes memory hookData) + /// @dev an unsafe swap function that does not check for slippage + /// @param key The pool key + /// @param zeroForOne The direction of the swap + /// @param amountIn The amount of input token, should be provided (as an estimate) for exact output swaps + /// @param amountOut The amount of output token can be provided as 0, for exact input swaps + /// @param hookData The data to pass to the hook + function swap(PoolKey memory key, bool zeroForOne, uint256 amountIn, uint256 amountOut, bytes memory hookData) external payable returns (BalanceDelta delta) { delta = abi.decode( - poolManager.unlock(abi.encode(msg.sender, key, zeroForOne, exactInput, amount, hookData)), (BalanceDelta) + poolManager.unlock(abi.encode(msg.sender, key, zeroForOne, amountIn, amountOut, hookData)), (BalanceDelta) ); uint256 ethBalance = address(this).balance; @@ -33,38 +41,53 @@ contract MinimalRouter is SafeCallback { } function _unlockCallback(bytes calldata data) internal override returns (bytes memory) { - (address sender, PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount, bytes memory hookData) = - abi.decode(data, (address, PoolKey, bool, bool, uint256, bytes)); + ( + address sender, + PoolKey memory key, + bool zeroForOne, + uint256 amountIn, + uint256 amountOut, + bytes memory hookData + ) = abi.decode(data, (address, PoolKey, bool, uint256, uint256, bytes)); - // for exact input swaps, send the input first to avoid PoolManager token balance issues - if (exactInput) { - zeroForOne - ? key.currency0.settle(poolManager, sender, amount, false) - : key.currency1.settle(poolManager, sender, amount, false); - } + // send the input first to avoid PoolManager token balance issues + zeroForOne + ? key.currency0.settle(poolManager, sender, amountIn, false) + : key.currency1.settle(poolManager, sender, amountIn, false); - BalanceDelta delta = poolManager.swap( + poolManager.swap( key, IPoolManager.SwapParams({ zeroForOne: zeroForOne, - amountSpecified: exactInput ? -int256(amount) : int256(amount), + amountSpecified: amountOut != 0 ? int256(amountOut) : -int256(amountIn), sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT }), hookData ); - if (!exactInput && delta.amount0() < 0) { - key.currency0.settle(poolManager, sender, uint256(int256(-delta.amount0())), false); - } else if (delta.amount0() > 0) { - key.currency0.take(poolManager, sender, uint256(int256(delta.amount0())), false); + // observe deltas + int256 delta0 = poolManager.currencyDelta(address(this), key.currency0); + int256 delta1 = poolManager.currencyDelta(address(this), key.currency1); + + // primarily take the output token, and excess amounts for exact output swaps + if (delta0 < 0) { + key.currency0.settle(poolManager, sender, uint256(-delta0), false); + } else if (delta0 > 0) { + key.currency0.take(poolManager, sender, uint256(delta0), false); } - if (!exactInput && delta.amount1() < 0) { - key.currency1.settle(poolManager, sender, uint256(int256(-delta.amount1())), false); - } else if (delta.amount1() > 0) { - key.currency1.take(poolManager, sender, uint256(int256(delta.amount1())), false); + if (delta1 < 0) { + key.currency1.settle(poolManager, sender, uint256(-delta1), false); + } else if (delta1 > 0) { + key.currency1.take(poolManager, sender, uint256(delta1), false); } - return abi.encode(delta); + // account for prepaid input against the observed deltas + BalanceDelta returnDelta = toBalanceDelta(int128(delta0), int128(delta1)) + + toBalanceDelta( + zeroForOne ? -int128(int256(amountIn)) : int128(0), zeroForOne ? int128(0) : -int128(int256(amountIn)) + ); + + return abi.encode(returnDelta); } } From 08252c3a1a7df7680786fa65e0f4234e9ed89110 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Mon, 24 Mar 2025 12:55:15 -0400 Subject: [PATCH 236/312] cleanup example router --- test/utils/MinimalRouter.sol | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/test/utils/MinimalRouter.sol b/test/utils/MinimalRouter.sol index bab8408..32475df 100644 --- a/test/utils/MinimalRouter.sol +++ b/test/utils/MinimalRouter.sol @@ -55,6 +55,7 @@ contract MinimalRouter is SafeCallback { ? key.currency0.settle(poolManager, sender, amountIn, false) : key.currency1.settle(poolManager, sender, amountIn, false); + // execute the swap poolManager.swap( key, IPoolManager.SwapParams({ @@ -69,18 +70,9 @@ contract MinimalRouter is SafeCallback { int256 delta0 = poolManager.currencyDelta(address(this), key.currency0); int256 delta1 = poolManager.currencyDelta(address(this), key.currency1); - // primarily take the output token, and excess amounts for exact output swaps - if (delta0 < 0) { - key.currency0.settle(poolManager, sender, uint256(-delta0), false); - } else if (delta0 > 0) { - key.currency0.take(poolManager, sender, uint256(delta0), false); - } - - if (delta1 < 0) { - key.currency1.settle(poolManager, sender, uint256(-delta1), false); - } else if (delta1 > 0) { - key.currency1.take(poolManager, sender, uint256(delta1), false); - } + // take the output + if (delta0 > 0) key.currency0.take(poolManager, sender, uint256(delta0), false); + if (delta1 > 0) key.currency1.take(poolManager, sender, uint256(delta1), false); // account for prepaid input against the observed deltas BalanceDelta returnDelta = toBalanceDelta(int128(delta0), int128(delta1)) From 8e354b9f8aff169ee464056c64c0ba1db960eacf Mon Sep 17 00:00:00 2001 From: saucepoint Date: Tue, 25 Mar 2025 16:50:54 -0400 Subject: [PATCH 237/312] refactor for swap fee test --- src/EulerSwapHook.sol | 75 +++++++++++--------- test/EulerSwapHook.fees.t.sol | 130 ++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 34 deletions(-) create mode 100644 test/EulerSwapHook.fees.t.sol diff --git a/src/EulerSwapHook.sol b/src/EulerSwapHook.sol index c4b8567..2371697 100644 --- a/src/EulerSwapHook.sol +++ b/src/EulerSwapHook.sol @@ -51,36 +51,53 @@ contract EulerSwapHook is EulerSwap, BaseHook { returns (bytes4, BeforeSwapDelta, uint24) { // determine inbound/outbound token based on 0->1 or 1->0 swap - (Currency inputCurrency, Currency outputCurrency) = - params.zeroForOne ? (key.currency0, key.currency1) : (key.currency1, key.currency0); - bool isExactInput = params.amountSpecified < 0; + bool zeroForOne = params.zeroForOne; - uint256 amountIn; + uint256 amountInWithoutFee; uint256 amountOut; + BeforeSwapDelta returnDelta; - if (isExactInput) { - amountIn = uint256(-params.amountSpecified); - amountOut = computeQuote(params.zeroForOne, uint256(-params.amountSpecified), true); - } else { - amountIn = computeQuote(params.zeroForOne, uint256(params.amountSpecified), false); - amountOut = uint256(params.amountSpecified); - } - - // take the input token, from the PoolManager to the Euler vault - // the debt will be paid by the swapper via the swap router - // TODO: can we optimize the transfer by pulling from PoolManager directly to Euler? - poolManager.take(inputCurrency, address(this), amountIn); - depositAssets(inputCurrency == key.currency0 ? vault0 : vault1, amountIn); + { + (Currency inputCurrency, Currency outputCurrency) = + params.zeroForOne ? (key.currency0, key.currency1) : (key.currency1, key.currency0); + + uint256 amountIn; + bool isExactInput = params.amountSpecified < 0; + if (isExactInput) { + amountIn = uint256(-params.amountSpecified); + amountOut = computeQuote(params.zeroForOne, uint256(-params.amountSpecified), true); + } else { + amountIn = computeQuote(params.zeroForOne, uint256(params.amountSpecified), false); + amountOut = uint256(params.amountSpecified); + } - // pay the output token, to the PoolManager from an Euler vault - // the credit will be forwarded to the swap router, which then forwards it to the swapper - poolManager.sync(outputCurrency); - withdrawAssets(outputCurrency == key.currency0 ? vault0 : vault1, amountOut, address(poolManager)); - poolManager.settle(); + // return the delta to the PoolManager, so it can process the accounting + // exact input: + // specifiedDelta = positive, to offset the input token taken by the hook (negative delta) + // unspecifiedDelta = negative, to offset the credit of the output token paid by the hook (positive delta) + // exact output: + // specifiedDelta = negative, to offset the output token paid by the hook (positive delta) + // unspecifiedDelta = positive, to offset the input token taken by the hook (negative delta) + returnDelta = isExactInput + ? toBeforeSwapDelta(amountIn.toInt128(), -(amountOut.toInt128())) + : toBeforeSwapDelta(-(amountOut.toInt128()), amountIn.toInt128()); + + // take the input token, from the PoolManager to the Euler vault + // the debt will be paid by the swapper via the swap router + // TODO: can we optimize the transfer by pulling from PoolManager directly to Euler? + poolManager.take(inputCurrency, address(this), amountIn); + amountInWithoutFee = depositAssets(zeroForOne ? vault0 : vault1, amountIn) * feeMultiplier / 1e18; + + // pay the output token, to the PoolManager from an Euler vault + // the credit will be forwarded to the swap router, which then forwards it to the swapper + poolManager.sync(outputCurrency); + withdrawAssets(zeroForOne ? vault1 : vault0, amountOut, address(poolManager)); + poolManager.settle(); + } { - uint256 newReserve0 = inputCurrency == key.currency0 ? (reserve0 + amountIn) : (reserve0 - amountOut); - uint256 newReserve1 = inputCurrency == key.currency1 ? (reserve1 + amountIn) : (reserve1 - amountOut); + uint256 newReserve0 = zeroForOne ? (reserve0 + amountInWithoutFee) : (reserve0 - amountOut); + uint256 newReserve1 = !zeroForOne ? (reserve1 + amountInWithoutFee) : (reserve1 - amountOut); require(newReserve0 <= type(uint112).max && newReserve1 <= type(uint112).max, Overflow()); require(verify(newReserve0, newReserve1), CurveViolation()); @@ -89,16 +106,6 @@ contract EulerSwapHook is EulerSwap, BaseHook { reserve1 = uint112(newReserve1); } - // return the delta to the PoolManager, so it can process the accounting - // exact input: - // specifiedDelta = positive, to offset the input token taken by the hook (negative delta) - // unspecifiedDelta = negative, to offset the credit of the output token paid by the hook (positive delta) - // exact output: - // specifiedDelta = negative, to offset the output token paid by the hook (positive delta) - // unspecifiedDelta = positive, to offset the input token taken by the hook (negative delta) - BeforeSwapDelta returnDelta = isExactInput - ? toBeforeSwapDelta(amountIn.toInt128(), -(amountOut.toInt128())) - : toBeforeSwapDelta(-(amountOut.toInt128()), amountIn.toInt128()); return (BaseHook.beforeSwap.selector, returnDelta, 0); } diff --git a/test/EulerSwapHook.fees.t.sol b/test/EulerSwapHook.fees.t.sol new file mode 100644 index 0000000..d8ffc8b --- /dev/null +++ b/test/EulerSwapHook.fees.t.sol @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; + +import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol"; +import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; +import {EulerSwapHook} from "../src/EulerSwapHook.sol"; + +import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; +import {IPoolManager, PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol"; +import {PoolSwapTest} from "@uniswap/v4-core/src/test/PoolSwapTest.sol"; +import {MinimalRouter} from "./utils/MinimalRouter.sol"; +import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; +import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; +import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; +import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; + +contract EulerSwapHookTest is EulerSwapTestBase { + using StateLibrary for IPoolManager; + + EulerSwapHook public eulerSwap; + + IPoolManager public poolManager; + PoolSwapTest public swapRouter; + MinimalRouter public minimalRouter; + + PoolSwapTest.TestSettings public settings = PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}); + + function setUp() public virtual override { + super.setUp(); + + poolManager = PoolManagerDeployer.deploy(address(this)); + swapRouter = new PoolSwapTest(poolManager); + minimalRouter = new MinimalRouter(poolManager); + + // set swap fee to 10 bips + eulerSwap = createEulerSwapHook(poolManager, 60e18, 60e18, 0.001e18, 1e18, 1e18, 0.4e18, 0.85e18); + eulerSwap.activate(); + + // confirm pool was created + assertFalse(eulerSwap.poolKey().currency1 == CurrencyLibrary.ADDRESS_ZERO); + (uint160 sqrtPriceX96,,,) = poolManager.getSlot0(eulerSwap.poolKey().toId()); + assertNotEq(sqrtPriceX96, 0); + } + + function test_SwapExactIn() public { + uint256 amountIn = 1e18; + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(minimalRouter), amountIn); + + bool zeroForOne = address(assetTST) < address(assetTST2); + BalanceDelta result = minimalRouter.swap(eulerSwap.poolKey(), zeroForOne, amountIn, 0, ""); + vm.stopPrank(); + + assertEq(assetTST.balanceOf(anyone), 0); + assertEq(assetTST2.balanceOf(anyone), amountOut); + + assertEq(zeroForOne ? uint256(-int256(result.amount0())) : uint256(-int256(result.amount1())), amountIn); + assertEq(zeroForOne ? uint256(int256(result.amount1())) : uint256(int256(result.amount0())), amountOut); + } + + /// @dev swapping with an amount that exceeds PoolManager's ERC20 token balance will revert + /// if the router does not pre-pay the input + function test_swapExactIn_revertWithoutTokenLiquidity() public { + uint256 amountIn = 1e18; // input amount exceeds PoolManager balance + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(swapRouter), amountIn); + + bool zeroForOne = address(assetTST) < address(assetTST2); + PoolKey memory poolKey = eulerSwap.poolKey(); + vm.expectRevert(); + _swap(poolKey, zeroForOne, true, amountIn); + vm.stopPrank(); + } + + function test_SwapExactOut() public { + uint256 amountOut = 1e18; + uint256 amountIn = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(minimalRouter), amountIn); + + bool zeroForOne = address(assetTST) < address(assetTST2); + BalanceDelta result = minimalRouter.swap(eulerSwap.poolKey(), zeroForOne, amountIn, amountOut, ""); + vm.stopPrank(); + + assertEq(assetTST.balanceOf(anyone), 0); + assertEq(assetTST2.balanceOf(anyone), amountOut); + + assertEq(zeroForOne ? uint256(-int256(result.amount0())) : uint256(-int256(result.amount1())), amountIn); + assertEq(zeroForOne ? uint256(int256(result.amount1())) : uint256(int256(result.amount0())), amountOut); + } + + /// @dev swapping with an amount that exceeds PoolManager's ERC20 token balance will revert + /// if the router does not pre-pay the input + function test_SwapExactOut_revertWithoutTokenLiquidity() public { + uint256 amountOut = 1e18; + uint256 amountIn = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(swapRouter), amountIn); + bool zeroForOne = address(assetTST) < address(assetTST2); + PoolKey memory poolKey = eulerSwap.poolKey(); + vm.expectRevert(); + _swap(poolKey, zeroForOne, false, amountOut); + vm.stopPrank(); + } + + function _swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount) internal { + IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ + zeroForOne: zeroForOne, + amountSpecified: exactInput ? -int256(amount) : int256(amount), + sqrtPriceLimitX96: zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1 + }); + swapRouter.swap(key, swapParams, settings, ""); + } +} From f10e7ce8e62d109f8514d7a34c55f579abf9ec46 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Tue, 25 Mar 2025 16:51:42 -0400 Subject: [PATCH 238/312] streamline --- test/EulerSwapHook.fees.t.sol | 39 ++--------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/test/EulerSwapHook.fees.t.sol b/test/EulerSwapHook.fees.t.sol index d8ffc8b..c6aa131 100644 --- a/test/EulerSwapHook.fees.t.sol +++ b/test/EulerSwapHook.fees.t.sol @@ -42,7 +42,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { assertNotEq(sqrtPriceX96, 0); } - function test_SwapExactIn() public { + function test_SwapExactIn_withLpFee() public { uint256 amountIn = 1e18; uint256 amountOut = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); @@ -63,24 +63,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { assertEq(zeroForOne ? uint256(int256(result.amount1())) : uint256(int256(result.amount0())), amountOut); } - /// @dev swapping with an amount that exceeds PoolManager's ERC20 token balance will revert - /// if the router does not pre-pay the input - function test_swapExactIn_revertWithoutTokenLiquidity() public { - uint256 amountIn = 1e18; // input amount exceeds PoolManager balance - - assetTST.mint(anyone, amountIn); - - vm.startPrank(anyone); - assetTST.approve(address(swapRouter), amountIn); - - bool zeroForOne = address(assetTST) < address(assetTST2); - PoolKey memory poolKey = eulerSwap.poolKey(); - vm.expectRevert(); - _swap(poolKey, zeroForOne, true, amountIn); - vm.stopPrank(); - } - - function test_SwapExactOut() public { + function test_SwapExactOut_withLpFee() public { uint256 amountOut = 1e18; uint256 amountIn = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); @@ -101,24 +84,6 @@ contract EulerSwapHookTest is EulerSwapTestBase { assertEq(zeroForOne ? uint256(int256(result.amount1())) : uint256(int256(result.amount0())), amountOut); } - /// @dev swapping with an amount that exceeds PoolManager's ERC20 token balance will revert - /// if the router does not pre-pay the input - function test_SwapExactOut_revertWithoutTokenLiquidity() public { - uint256 amountOut = 1e18; - uint256 amountIn = - periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); - - assetTST.mint(anyone, amountIn); - - vm.startPrank(anyone); - assetTST.approve(address(swapRouter), amountIn); - bool zeroForOne = address(assetTST) < address(assetTST2); - PoolKey memory poolKey = eulerSwap.poolKey(); - vm.expectRevert(); - _swap(poolKey, zeroForOne, false, amountOut); - vm.stopPrank(); - } - function _swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount) internal { IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ zeroForOne: zeroForOne, From fe42bcffff55085b2499b5ef9593eb182e880831 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Tue, 25 Mar 2025 16:54:43 -0400 Subject: [PATCH 239/312] reuse declared variable --- src/EulerSwapHook.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/EulerSwapHook.sol b/src/EulerSwapHook.sol index 2371697..ef40683 100644 --- a/src/EulerSwapHook.sol +++ b/src/EulerSwapHook.sol @@ -59,15 +59,15 @@ contract EulerSwapHook is EulerSwap, BaseHook { { (Currency inputCurrency, Currency outputCurrency) = - params.zeroForOne ? (key.currency0, key.currency1) : (key.currency1, key.currency0); + zeroForOne ? (key.currency0, key.currency1) : (key.currency1, key.currency0); uint256 amountIn; bool isExactInput = params.amountSpecified < 0; if (isExactInput) { amountIn = uint256(-params.amountSpecified); - amountOut = computeQuote(params.zeroForOne, uint256(-params.amountSpecified), true); + amountOut = computeQuote(zeroForOne, uint256(-params.amountSpecified), true); } else { - amountIn = computeQuote(params.zeroForOne, uint256(params.amountSpecified), false); + amountIn = computeQuote(zeroForOne, uint256(params.amountSpecified), false); amountOut = uint256(params.amountSpecified); } From 871bf6a39f608dca479740ad907aafc60dc3d4c6 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Tue, 25 Mar 2025 18:24:00 -0400 Subject: [PATCH 240/312] assert fee and reserves logic --- test/EulerSwapHook.fees.t.sol | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/EulerSwapHook.fees.t.sol b/test/EulerSwapHook.fees.t.sol index c6aa131..ca09ee6 100644 --- a/test/EulerSwapHook.fees.t.sol +++ b/test/EulerSwapHook.fees.t.sol @@ -43,7 +43,10 @@ contract EulerSwapHookTest is EulerSwapTestBase { } function test_SwapExactIn_withLpFee() public { + (uint112 r0, uint112 r1,) = eulerSwap.getReserves(); + uint256 amountIn = 1e18; + uint256 amountInWithoutFee = amountIn * eulerSwap.feeMultiplier() / 1e18; uint256 amountOut = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); @@ -61,12 +64,26 @@ contract EulerSwapHookTest is EulerSwapTestBase { assertEq(zeroForOne ? uint256(-int256(result.amount0())) : uint256(-int256(result.amount1())), amountIn); assertEq(zeroForOne ? uint256(int256(result.amount1())) : uint256(int256(result.amount0())), amountOut); + + // assert fees were not added to the reserves + (uint112 r0New, uint112 r1New,) = eulerSwap.getReserves(); + if (zeroForOne) { + assertEq(r0New, r0 + amountInWithoutFee); + assertEq(r1New, r1 - amountOut); + } else { + // oneForZero, so the curve received asset1 + assertEq(r0New, r0 - amountOut); + assertEq(r1New, r1 + amountInWithoutFee); + } } function test_SwapExactOut_withLpFee() public { + (uint112 r0, uint112 r1,) = eulerSwap.getReserves(); + uint256 amountOut = 1e18; uint256 amountIn = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + uint256 amountInWithoutFee = (amountIn * 1e18) / (2e18 - eulerSwap.feeMultiplier()); assetTST.mint(anyone, amountIn); @@ -82,6 +99,17 @@ contract EulerSwapHookTest is EulerSwapTestBase { assertEq(zeroForOne ? uint256(-int256(result.amount0())) : uint256(-int256(result.amount1())), amountIn); assertEq(zeroForOne ? uint256(int256(result.amount1())) : uint256(int256(result.amount0())), amountOut); + + // assert fees were not added to the reserves + (uint112 r0New, uint112 r1New,) = eulerSwap.getReserves(); + if (zeroForOne) { + assertEq(r0New, r0 + amountInWithoutFee, "A"); + assertEq(r1New, r1 - amountOut, "B"); + } else { + // oneForZero, so the curve received asset1 + assertEq(r0New, r0 - amountOut, "C"); + assertEq(r1New, r1 + amountInWithoutFee, "D"); + } } function _swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount) internal { From 4237afcd0b7ac728d78228821c5389f13cc9ec53 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Thu, 27 Mar 2025 11:14:50 -0400 Subject: [PATCH 241/312] unit tests for fee calculations --- test/Fees.t.sol | 110 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 test/Fees.t.sol diff --git a/test/Fees.t.sol b/test/Fees.t.sol new file mode 100644 index 0000000..3f83fb6 --- /dev/null +++ b/test/Fees.t.sol @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; + +import {Test, console} from "forge-std/Test.sol"; +import {IEVault, IEulerSwap, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; + +contract FeesTest is EulerSwapTestBase { + EulerSwap public eulerSwap; + + function setUp() public virtual override { + super.setUp(); + + eulerSwap = createEulerSwap(60e18, 60e18, 0, 1e18, 1e18, 0.9e18, 0.9e18); + } + + function test_fees_exactIn() public monotonicHolderNAV { + int256 origNav = getHolderNAV(); + uint256 fee = 0.05e18; + + // No fees + + uint256 amountInNoFees = 1e18; + uint256 amountOutNoFees = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountInNoFees); + assertApproxEqAbs(amountOutNoFees, 0.9983e18, 0.0001e18); + + // With fees: Increase input amount so that corresponding output amount matches + + eulerSwap = createEulerSwap(60e18, 60e18, fee, 1e18, 1e18, 0.9e18, 0.9e18); + + uint256 amountIn = amountInNoFees * 1e18 / (1e18 - fee); + uint256 amountOut = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + assertApproxEqAbs(amountOut, amountOutNoFees, 1); // Same except for possible rounding down by 1 + + // Actually execute swap + + assetTST.mint(address(this), amountIn); + assetTST.transfer(address(eulerSwap), amountIn); + + // Pulling out one extra reverts... + + vm.expectRevert(EulerSwap.CurveViolation.selector); + eulerSwap.swap(0, amountOut + 1, address(this), ""); + + // Just right: + + eulerSwap.swap(0, amountOut, address(this), ""); + + // Swapper received their quoted amount: + + assertEq(assetTST2.balanceOf(address(this)), amountOut); + + // eulerSwap instance is empty: + + assertEq(assetTST.balanceOf(address(eulerSwap)), 0); + assertEq(assetTST2.balanceOf(address(eulerSwap)), 0); + + // Holder's NAV increased by fee amount, plus slightly extra because we are not at curve equilibrium point + + assertGt(getHolderNAV(), origNav + int256(amountIn - amountInNoFees)); + assertEq(eTST.balanceOf(address(holder)), 10e18 + amountIn); + assertEq(eTST2.balanceOf(address(holder)), 10e18 - amountOut); + } + + function test_fees_exactOut() public monotonicHolderNAV { + int256 origNav = getHolderNAV(); + uint256 fee = 0.05e18; + + // No fees + + uint256 amountOut = 1e18; + uint256 amountInNoFees = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + assertApproxEqAbs(amountInNoFees, 1.0017e18, 0.0001e18); + + // With fees: Increase input amount so output amount stays same + + eulerSwap = createEulerSwap(60e18, 60e18, fee, 1e18, 1e18, 0.9e18, 0.9e18); + + uint256 amountIn = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + assertApproxEqAbs(amountIn, amountInNoFees * 1e18 / (1e18 - fee), 1); // Same except for possible rounding up by 1 + + // Actually execute swap + + assetTST.mint(address(this), amountIn); + assetTST.transfer(address(eulerSwap), amountIn); + + // Pulling out one extra reverts... + + vm.expectRevert(EulerSwap.CurveViolation.selector); + eulerSwap.swap(0, amountOut + 1, address(this), ""); + + // Just right: + + eulerSwap.swap(0, amountOut, address(this), ""); + + // Swapper received their quoted amount: + + assertEq(assetTST2.balanceOf(address(this)), amountOut); + + // eulerSwap instance is empty: + + assertEq(assetTST.balanceOf(address(eulerSwap)), 0); + assertEq(assetTST2.balanceOf(address(eulerSwap)), 0); + + // Holder's NAV increased by fee amount, plus slightly extra because we are not at curve equilibrium point + + assertGt(getHolderNAV(), origNav + int256(amountIn - amountInNoFees)); + assertEq(eTST.balanceOf(address(holder)), 10e18 + amountIn); + assertEq(eTST2.balanceOf(address(holder)), 10e18 - amountOut); + } +} From 822a54bb87d64043d2e247d6d351bc946950f36d Mon Sep 17 00:00:00 2001 From: saucepoint Date: Fri, 28 Mar 2025 14:53:33 -0400 Subject: [PATCH 242/312] forge fmt --- test/Fees.t.sol | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/Fees.t.sol b/test/Fees.t.sol index 3f83fb6..dc3c753 100644 --- a/test/Fees.t.sol +++ b/test/Fees.t.sol @@ -20,7 +20,8 @@ contract FeesTest is EulerSwapTestBase { // No fees uint256 amountInNoFees = 1e18; - uint256 amountOutNoFees = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountInNoFees); + uint256 amountOutNoFees = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountInNoFees); assertApproxEqAbs(amountOutNoFees, 0.9983e18, 0.0001e18); // With fees: Increase input amount so that corresponding output amount matches @@ -28,7 +29,8 @@ contract FeesTest is EulerSwapTestBase { eulerSwap = createEulerSwap(60e18, 60e18, fee, 1e18, 1e18, 0.9e18, 0.9e18); uint256 amountIn = amountInNoFees * 1e18 / (1e18 - fee); - uint256 amountOut = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); assertApproxEqAbs(amountOut, amountOutNoFees, 1); // Same except for possible rounding down by 1 // Actually execute swap @@ -68,14 +70,16 @@ contract FeesTest is EulerSwapTestBase { // No fees uint256 amountOut = 1e18; - uint256 amountInNoFees = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + uint256 amountInNoFees = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); assertApproxEqAbs(amountInNoFees, 1.0017e18, 0.0001e18); // With fees: Increase input amount so output amount stays same eulerSwap = createEulerSwap(60e18, 60e18, fee, 1e18, 1e18, 0.9e18, 0.9e18); - uint256 amountIn = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + uint256 amountIn = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); assertApproxEqAbs(amountIn, amountInNoFees * 1e18 / (1e18 - fee), 1); // Same except for possible rounding up by 1 // Actually execute swap From 7abb85da24d087536799bec3ebb1326b83efa6e6 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Fri, 28 Mar 2025 14:53:58 -0400 Subject: [PATCH 243/312] add NAV assertion & fix exact out fee math --- test/EulerSwapHook.fees.t.sol | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/test/EulerSwapHook.fees.t.sol b/test/EulerSwapHook.fees.t.sol index ca09ee6..21215c4 100644 --- a/test/EulerSwapHook.fees.t.sol +++ b/test/EulerSwapHook.fees.t.sol @@ -43,6 +43,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { } function test_SwapExactIn_withLpFee() public { + int256 origNav = getHolderNAV(); (uint112 r0, uint112 r1,) = eulerSwap.getReserves(); uint256 amountIn = 1e18; @@ -75,15 +76,20 @@ contract EulerSwapHookTest is EulerSwapTestBase { assertEq(r0New, r0 - amountOut); assertEq(r1New, r1 + amountInWithoutFee); } + + assertGt(getHolderNAV(), origNav + int256(amountIn - amountInWithoutFee)); } function test_SwapExactOut_withLpFee() public { + int256 origNav = getHolderNAV(); (uint112 r0, uint112 r1,) = eulerSwap.getReserves(); uint256 amountOut = 1e18; uint256 amountIn = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); - uint256 amountInWithoutFee = (amountIn * 1e18) / (2e18 - eulerSwap.feeMultiplier()); + + // inverse of the fee math in Periphery + uint256 amountInWithoutFee = (amountIn * eulerSwap.feeMultiplier() - eulerSwap.feeMultiplier()) / 1e18; assetTST.mint(anyone, amountIn); @@ -103,13 +109,15 @@ contract EulerSwapHookTest is EulerSwapTestBase { // assert fees were not added to the reserves (uint112 r0New, uint112 r1New,) = eulerSwap.getReserves(); if (zeroForOne) { - assertEq(r0New, r0 + amountInWithoutFee, "A"); - assertEq(r1New, r1 - amountOut, "B"); + assertEq(r0New, r0 + amountInWithoutFee + 1); // 1 wei of imprecision + assertEq(r1New, r1 - amountOut); } else { // oneForZero, so the curve received asset1 - assertEq(r0New, r0 - amountOut, "C"); - assertEq(r1New, r1 + amountInWithoutFee, "D"); + assertEq(r0New, r0 - amountOut); + assertEq(r1New, r1 + amountInWithoutFee); } + + assertGt(getHolderNAV(), origNav + int256(amountIn - amountInWithoutFee)); } function _swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount) internal { From dd7e84347332f6cbf0c635b7484e25647abc5c98 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Fri, 28 Mar 2025 15:23:21 -0400 Subject: [PATCH 244/312] remove dead function --- test/EulerSwapHook.fees.t.sol | 9 --------- 1 file changed, 9 deletions(-) diff --git a/test/EulerSwapHook.fees.t.sol b/test/EulerSwapHook.fees.t.sol index 21215c4..f91bbae 100644 --- a/test/EulerSwapHook.fees.t.sol +++ b/test/EulerSwapHook.fees.t.sol @@ -119,13 +119,4 @@ contract EulerSwapHookTest is EulerSwapTestBase { assertGt(getHolderNAV(), origNav + int256(amountIn - amountInWithoutFee)); } - - function _swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount) internal { - IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ - zeroForOne: zeroForOne, - amountSpecified: exactInput ? -int256(amount) : int256(amount), - sqrtPriceLimitX96: zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1 - }); - swapRouter.swap(key, swapParams, settings, ""); - } } From c7f93ded3becea9f5e88b65ce02865e47d432473 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 2 Apr 2025 00:09:30 -0400 Subject: [PATCH 245/312] add eulerswaphook audit note --- docs/audits/EulerSwapHook_Audit_Scope.md | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 docs/audits/EulerSwapHook_Audit_Scope.md diff --git a/docs/audits/EulerSwapHook_Audit_Scope.md b/docs/audits/EulerSwapHook_Audit_Scope.md new file mode 100644 index 0000000..8d31df3 --- /dev/null +++ b/docs/audits/EulerSwapHook_Audit_Scope.md @@ -0,0 +1,46 @@ +# EulerSwapHook Audit + +Through a new partnership between Euler Labs and Uniswap Foundation, the teams intend to expose EulerSwap's core logic and mechanisms via a Uniswap v4 Hook interface. + +This is primarily done by inheriting `EulerSwap.sol:EulerSwap`, i.e. `EulerSwapHook is EulerSwap, BaseHook`, and implementing a "custom curve" via `beforeSwap`. The implementation will allow integrators, interfaces, and aggregators, to trade on EulerSwap as-if it is any other Uniswap v4 Pool + +```solidity +// assuming the EulerSwapHook was instantiated via EulerSwapFactory +PoolKey memory poolKey = PoolKey({ + currency0: currency0, + currency1: currency1, + fee: fee, + tickSpacing: 60, + hooks: IHooks(address(eulerSwapHook)) +}); + +minimalRouter.swap(poolKey, zeroForOne, amountIn, 0); +``` + + +## Audit Scope + +The scope of audit involves the code-diff introduced by [PR #48](https://github.com/euler-xyz/euler-swap/pull/48/files). **As of Apr 1st, 2025, the diff is subject to change but will be code-complete by the audit start time.** + +Major Changes will include: + +* Replacing `binarySearch` quoting algorithm with a closed-form formula +* Implementing a protocol fee, as a percentage of LP fees, enacted by governance + +As for the files in scope, only files from `src/` should be considered: + +``` +├── src +│ ├── EulerSwapFactory.sol +│ ├── EulerSwapHook.sol +│ └── utils +│ └── HookMiner.sol +``` + +## Known Caveats + +### Prepaid Inputs + +Due to technical requirements, EulerSwapHook must take the input token from PoolManager and deposit it into Euler Vaults. It will appear that EulerSwapHook can only support input sizes of `IERC20.balanceOf(PoolManager)`. However swap routers can pre-emptively send input tokens (from user wallet to PoolManager) prior to calling `poolManager.swap` to get around this limitation. + +An example `test/utils/MinimalRouter.sol` is provided as an example. \ No newline at end of file From 0637b6f363810023db4886dcf93010d412ea7368 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 2 Apr 2025 18:45:25 +0700 Subject: [PATCH 246/312] port over cool stuff from hub --- script/DeployPool.s.sol | 2 +- src/EulerSwapFactory.sol | 90 +++++++++++++++++++----- src/interfaces/IEulerSwapFactory.sol | 7 ++ test/EulerSwapFactoryTest.t.sol | 100 +++++++++++++++++++++++++-- test/EulerSwapTestBase.t.sol | 22 +++++- test/Fees.t.sol | 12 ++-- 6 files changed, 205 insertions(+), 28 deletions(-) diff --git a/script/DeployPool.s.sol b/script/DeployPool.s.sol index e1dedd6..94c47c1 100644 --- a/script/DeployPool.s.sol +++ b/script/DeployPool.s.sol @@ -57,7 +57,7 @@ contract DeployPool is ScriptUtil { evc.batch(items); vm.stopBroadcast(); - address pool = factory.eulerAccountToPool(eulerAccount); + (address pool,,) = factory.getEulerAccountState(eulerAccount); string memory outputScriptFileName = "DeployPool_output.json"; diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index dcde2fd..2136e9f 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -10,12 +10,13 @@ import {GenericFactory} from "evk/GenericFactory/GenericFactory.sol"; /// @custom:security-contact security@euler.xyz /// @author Euler Labs (https://www.eulerlabs.com/) contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { - /// @dev An array to store all pools addresses. - address[] public allPools; - /// @dev Mapping between euler account and deployed pool that is currently set as operator - mapping(address eulerAccount => address operator) public eulerAccountToPool; /// @dev Vaults must be deployed by this factory address public immutable evkFactory; + /// @dev An array to store all pools addresses. + address[] public allPools; + /// @dev Mapping between euler account and EulerAccountState + mapping(address eulerAccount => EulerAccountState state) private eulerAccountState; + mapping(address asset0 => mapping(address asset1 => address[])) private poolMap; event PoolDeployed( address indexed asset0, @@ -32,6 +33,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { uint256 concentrationY, address pool ); + event PoolUninstalled(address indexed asset0, address indexed asset1, address indexed eulerAccount, address pool); error InvalidQuery(); error Unauthorized(); @@ -56,9 +58,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { EulerSwap pool = new EulerSwap{salt: keccak256(abi.encode(params.eulerAccount, salt))}(params, curveParams); - checkEulerAccountOperators(params.eulerAccount, address(pool)); - - allPools.push(address(pool)); + checkAndUpdateEulerAccountState(params.eulerAccount, address(pool)); EulerSwap(pool).activate(); @@ -114,6 +114,14 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { return allPools.length; } + function getEulerAccountState(address eulerAccount) external view returns (address, uint48, uint48) { + return ( + eulerAccountState[eulerAccount].pool, + eulerAccountState[eulerAccount].allPoolsIndex, + eulerAccountState[eulerAccount].poolMapIndex + ); + } + /// @inheritdoc IEulerSwapFactory function getAllPoolsListSlice(uint256 _start, uint256 _end) external view returns (address[] memory) { uint256 length = allPools.length; @@ -128,20 +136,68 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { return allPoolsList; } - /// @notice Validates operator authorization for euler account. First checks if the account has an existing operator - /// and ensures it is deauthorized. Then verifies the new pool is authorized as an operator. Finally, updates the - /// mapping to track the new pool as the account's operator. + /// @notice Validates operator authorization for euler account and update the relevant EulerAccountState. /// @param eulerAccount The address of the euler account. - /// @param newPool The address of the new pool. - function checkEulerAccountOperators(address eulerAccount, address newPool) internal { - address operator = eulerAccountToPool[eulerAccount]; + /// @param newOperator The address of the new pool. + function checkAndUpdateEulerAccountState(address eulerAccount, address newOperator) internal { + require(evc.isAccountOperatorAuthorized(eulerAccount, newOperator), OperatorNotInstalled()); + + (address newOpAsset0, address newOpAsset1) = _getAssets(newOperator); + address oldOperator = eulerAccountState[eulerAccount].pool; + + if (oldOperator != address(0)) { + require(!evc.isAccountOperatorAuthorized(eulerAccount, oldOperator), OldOperatorStillInstalled()); + + // replace pool address in allPools array + _updateInArray(allPools, eulerAccountState[eulerAccount].allPoolsIndex, newOperator); + + eulerAccountState[eulerAccount].pool = newOperator; - if (operator != address(0)) { - require(!evc.isAccountOperatorAuthorized(eulerAccount, operator), OldOperatorStillInstalled()); + (address oldOpAsset0, address oldOpAsset1) = _getAssets(oldOperator); + + // if deploying new pool for same assets pair, just update poolMap without pop() + // else, we need to go the traditional path, reduce the array size, update eulerAccount poolMapIndex and push new one + if (oldOpAsset0 == newOpAsset0 && oldOpAsset1 == newOpAsset1) { + _updateInArray( + poolMap[newOpAsset0][newOpAsset1], eulerAccountState[eulerAccount].poolMapIndex, newOperator + ); + } else { + _removeFromArray(poolMap[oldOpAsset0][oldOpAsset1], eulerAccountState[eulerAccount].poolMapIndex); + + eulerAccountState[eulerAccount].poolMapIndex = uint48(poolMap[newOpAsset0][newOpAsset1].length); + + _pushInArray(poolMap[newOpAsset0][newOpAsset1], newOperator); + } + + emit PoolUninstalled(oldOpAsset0, oldOpAsset1, eulerAccount, oldOperator); + } else { + address[] storage poolMapArray = poolMap[newOpAsset0][newOpAsset1]; + + eulerAccountState[eulerAccount] = EulerAccountState({ + pool: newOperator, + allPoolsIndex: uint48(allPools.length), + poolMapIndex: uint48(poolMapArray.length) + }); + + _pushInArray(allPools, newOperator); + _pushInArray(poolMapArray, newOperator); } + } + + function _updateInArray(address[] storage arr, uint256 index, address _newValue) internal { + arr[index] = _newValue; + } - require(evc.isAccountOperatorAuthorized(eulerAccount, newPool), OperatorNotInstalled()); + function _pushInArray(address[] storage arr, address _newValue) internal { + arr.push(_newValue); + } + + function _removeFromArray(address[] storage arr, uint256 index) internal { + arr[index] = arr[arr.length - 1]; + arr.pop(); + } - eulerAccountToPool[eulerAccount] = newPool; + function _getAssets(address pool) internal view returns (address, address) { + return (EulerSwap(pool).asset0(), EulerSwap(pool).asset1()); } } diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol index 3d1b164..b4ade14 100644 --- a/src/interfaces/IEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -4,6 +4,12 @@ pragma solidity >=0.8.0; import {IEulerSwap} from "./IEulerSwap.sol"; interface IEulerSwapFactory { + struct EulerAccountState { + address pool; + uint48 allPoolsIndex; + uint48 poolMapIndex; + } + /// @notice Deploy a new EulerSwap pool with the given parameters /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from /// the euler account address and provided salt parameter. This allows the pool address to be @@ -16,6 +22,7 @@ interface IEulerSwapFactory { external returns (address); + function getEulerAccountState(address eulerAccount) external view returns (address, uint48, uint48); /// @notice Compute the address of a new EulerSwap pool with the given parameters /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from /// the euler account address and provided salt parameter. This allows the pool address to be diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index fe9fb73..6be1db2 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -19,6 +19,8 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { function testDeployPool() public { uint256 allPoolsLengthBefore = eulerSwapFactory.allPoolsLength(); + // test when new pool not set as operator + bytes32 salt = bytes32(uint256(1234)); IEulerSwap.Params memory poolParams = IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 0); @@ -26,7 +28,22 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { address predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); - IEVC.BatchItem[] memory items = new IEVC.BatchItem[](2); + IEVC.BatchItem[] memory items = new IEVC.BatchItem[](1); + + items[0] = IEVC.BatchItem({ + onBehalfOfAccount: holder, + targetContract: address(eulerSwapFactory), + value: 0, + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) + }); + + vm.prank(holder); + vm.expectRevert(EulerSwapFactory.OperatorNotInstalled.selector); + evc.batch(items); + + // success test + + items = new IEVC.BatchItem[](2); items[0] = IEVC.BatchItem({ onBehalfOfAccount: address(0), @@ -44,27 +61,100 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { vm.prank(holder); evc.batch(items); - EulerSwap eulerSwap = EulerSwap(eulerSwapFactory.eulerAccountToPool(holder)); + (address eulerSwap,,) = eulerSwapFactory.getEulerAccountState(holder); uint256 allPoolsLengthAfter = eulerSwapFactory.allPoolsLength(); assertEq(allPoolsLengthAfter - allPoolsLengthBefore, 1); address[] memory poolsList = eulerSwapFactory.getAllPoolsListSlice(0, type(uint256).max); assertEq(poolsList.length, 1); - assertEq(poolsList[0], address(eulerSwap)); + assertEq(poolsList[0], eulerSwap); assertEq(eulerSwapFactory.allPools(0), address(eulerSwap)); - items = new IEVC.BatchItem[](1); + // test when deploying second pool while old pool is still set as operator + + salt = bytes32(uint256(12345)); + predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); items[0] = IEVC.BatchItem({ + onBehalfOfAccount: address(0), + targetContract: address(evc), + value: 0, + data: abi.encodeCall(evc.setAccountOperator, (holder, predictedAddress, true)) + }); + items[1] = IEVC.BatchItem({ onBehalfOfAccount: holder, targetContract: address(eulerSwapFactory), value: 0, - data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, bytes32(uint256(12345)))) + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) }); vm.prank(holder); vm.expectRevert(EulerSwapFactory.OldOperatorStillInstalled.selector); evc.batch(items); + + // test deploying new pool for same assets pair as old one + (address oldPool,,) = eulerSwapFactory.getEulerAccountState(holder); + salt = bytes32(uint256(123456)); + predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); + + items = new IEVC.BatchItem[](3); + items[0] = IEVC.BatchItem({ + onBehalfOfAccount: address(0), + targetContract: address(evc), + value: 0, + data: abi.encodeCall(evc.setAccountOperator, (holder, oldPool, false)) + }); + items[1] = IEVC.BatchItem({ + onBehalfOfAccount: address(0), + targetContract: address(evc), + value: 0, + data: abi.encodeCall(evc.setAccountOperator, (holder, predictedAddress, true)) + }); + items[2] = IEVC.BatchItem({ + onBehalfOfAccount: holder, + targetContract: address(eulerSwapFactory), + value: 0, + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) + }); + + vm.prank(holder); + evc.batch(items); + + (address pool,,) = eulerSwapFactory.getEulerAccountState(holder); + assertEq(pool, predictedAddress); + + // test deploying new pool for different assets pair as old one + (oldPool,,) = eulerSwapFactory.getEulerAccountState(holder); + poolParams = IEulerSwap.Params(address(eTST), address(eTST3), holder, 1e18, 1e18, 1e18, 1e18, 0); + + salt = bytes32(uint256(1234567)); + predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); + + items = new IEVC.BatchItem[](3); + items[0] = IEVC.BatchItem({ + onBehalfOfAccount: address(0), + targetContract: address(evc), + value: 0, + data: abi.encodeCall(evc.setAccountOperator, (holder, oldPool, false)) + }); + items[1] = IEVC.BatchItem({ + onBehalfOfAccount: address(0), + targetContract: address(evc), + value: 0, + data: abi.encodeCall(evc.setAccountOperator, (holder, predictedAddress, true)) + }); + items[2] = IEVC.BatchItem({ + onBehalfOfAccount: holder, + targetContract: address(eulerSwapFactory), + value: 0, + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) + }); + + vm.prank(holder); + evc.batch(items); + + (pool,,) = eulerSwapFactory.getEulerAccountState(holder); + assertEq(pool, predictedAddress); } function testInvalidGetAllPoolsListSliceQuery() public { diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index 9c2d862..e1c13c8 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.24; import {Test, console} from "forge-std/Test.sol"; -import {EVaultTestBase, TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; +import {EVaultTestBase, TestERC20, IRMTestDefault} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; import {IEulerSwap, IEVC, EulerSwap} from "../src/EulerSwap.sol"; import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; @@ -14,6 +14,9 @@ contract EulerSwapTestBase is EVaultTestBase { address public recipient = makeAddr("recipient"); address public anyone = makeAddr("anyone"); + TestERC20 assetTST3; + IEVault public eTST3; + EulerSwapPeriphery public periphery; modifier monotonicHolderNAV() { @@ -27,28 +30,45 @@ contract EulerSwapTestBase is EVaultTestBase { periphery = new EulerSwapPeriphery(); + // deploy more vaults + assetTST3 = new TestERC20("Test Token 3", "TST3", 18, false); + eTST3 = IEVault( + factory.createProxy(address(0), true, abi.encodePacked(address(assetTST3), address(oracle), unitOfAccount)) + ); + eTST3.setHookConfig(address(0), 0); + eTST3.setInterestRateModel(address(new IRMTestDefault())); + eTST3.setMaxLiquidationDiscount(0.2e4); + eTST3.setFeeReceiver(feeReceiver); + // Vault config eTST.setLTV(address(eTST2), 0.9e4, 0.9e4, 0); eTST2.setLTV(address(eTST), 0.9e4, 0.9e4, 0); + eTST.setLTV(address(eTST3), 0.9e4, 0.9e4, 0); // Pricing oracle.setPrice(address(assetTST), unitOfAccount, 1e18); oracle.setPrice(address(assetTST2), unitOfAccount, 1e18); + oracle.setPrice(address(assetTST3), unitOfAccount, 1e18); oracle.setPrice(address(eTST), unitOfAccount, 1e18); oracle.setPrice(address(eTST2), unitOfAccount, 1e18); + oracle.setPrice(address(eTST3), unitOfAccount, 1e18); oracle.setPrice(address(assetTST), address(assetTST2), 1e18); oracle.setPrice(address(assetTST2), address(assetTST), 1e18); + oracle.setPrice(address(assetTST), address(assetTST3), 1e18); + oracle.setPrice(address(assetTST3), address(assetTST), 1e18); // Funding mintAndDeposit(depositor, eTST, 100e18); mintAndDeposit(depositor, eTST2, 100e18); + mintAndDeposit(depositor, eTST3, 100e18); mintAndDeposit(holder, eTST, 10e18); mintAndDeposit(holder, eTST2, 10e18); + mintAndDeposit(holder, eTST3, 10e18); } function skimAll(EulerSwap ml, bool order) public { diff --git a/test/Fees.t.sol b/test/Fees.t.sol index 3f83fb6..dc3c753 100644 --- a/test/Fees.t.sol +++ b/test/Fees.t.sol @@ -20,7 +20,8 @@ contract FeesTest is EulerSwapTestBase { // No fees uint256 amountInNoFees = 1e18; - uint256 amountOutNoFees = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountInNoFees); + uint256 amountOutNoFees = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountInNoFees); assertApproxEqAbs(amountOutNoFees, 0.9983e18, 0.0001e18); // With fees: Increase input amount so that corresponding output amount matches @@ -28,7 +29,8 @@ contract FeesTest is EulerSwapTestBase { eulerSwap = createEulerSwap(60e18, 60e18, fee, 1e18, 1e18, 0.9e18, 0.9e18); uint256 amountIn = amountInNoFees * 1e18 / (1e18 - fee); - uint256 amountOut = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); assertApproxEqAbs(amountOut, amountOutNoFees, 1); // Same except for possible rounding down by 1 // Actually execute swap @@ -68,14 +70,16 @@ contract FeesTest is EulerSwapTestBase { // No fees uint256 amountOut = 1e18; - uint256 amountInNoFees = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + uint256 amountInNoFees = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); assertApproxEqAbs(amountInNoFees, 1.0017e18, 0.0001e18); // With fees: Increase input amount so output amount stays same eulerSwap = createEulerSwap(60e18, 60e18, fee, 1e18, 1e18, 0.9e18, 0.9e18); - uint256 amountIn = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); + uint256 amountIn = + periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); assertApproxEqAbs(amountIn, amountInNoFees * 1e18 / (1e18 - fee), 1); // Same except for possible rounding up by 1 // Actually execute swap From d6b1d030053dbdd380d7ea8cdff881d8a20577a4 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 2 Apr 2025 19:00:56 +0700 Subject: [PATCH 247/312] natspec --- src/EulerSwapFactory.sol | 18 ++++++++++++++++++ src/interfaces/IEulerSwapFactory.sol | 8 ++++++++ 2 files changed, 26 insertions(+) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 2136e9f..1d36bbe 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -114,6 +114,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { return allPools.length; } + /// @inheritdoc IEulerSwapFactory function getEulerAccountState(address eulerAccount) external view returns (address, uint48, uint48) { return ( eulerAccountState[eulerAccount].pool, @@ -184,19 +185,36 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { } } + /// @notice Updates an element at a specific index in an array + /// @dev Directly modifies the array element at the given index with a new value + /// @param arr The storage array to update + /// @param index The index of the element to update + /// @param _newValue The new value to set at the specified index function _updateInArray(address[] storage arr, uint256 index, address _newValue) internal { arr[index] = _newValue; } + /// @notice Adds a new element to the end of an array + /// @dev Uses the push operation to append a new value to the array + /// @param arr The storage array to append to + /// @param _newValue The new value to append to the array function _pushInArray(address[] storage arr, address _newValue) internal { arr.push(_newValue); } + /// @notice Removes an element from an array at a specific index + /// @dev Uses the swap-and-pop pattern to remove an element while maintaining array order + /// @param arr The storage array to remove from + /// @param index The index of the element to remove function _removeFromArray(address[] storage arr, uint256 index) internal { arr[index] = arr[arr.length - 1]; arr.pop(); } + /// @notice Retrieves the asset addresses for a given pool + /// @dev Calls the pool contract to get its asset0 and asset1 addresses + /// @param pool The address of the pool to query + /// @return The addresses of asset0 and asset1 in the pool function _getAssets(address pool) internal view returns (address, address) { return (EulerSwap(pool).asset0(), EulerSwap(pool).asset1()); } diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol index b4ade14..687d09a 100644 --- a/src/interfaces/IEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -22,7 +22,15 @@ interface IEulerSwapFactory { external returns (address); + /// @notice Retrieves the state information for a given Euler account + /// @dev Returns the current pool address, index in allPools array, and index in poolMap array + /// for the specified Euler account + /// @param eulerAccount The address of the Euler account to query + /// @return pool The address of the current pool associated with the Euler account + /// @return allPoolsIndex The index of the pool in the allPools array + /// @return poolMapIndex The index of the pool in the poolMap array for its asset pair function getEulerAccountState(address eulerAccount) external view returns (address, uint48, uint48); + /// @notice Compute the address of a new EulerSwap pool with the given parameters /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from /// the euler account address and provided salt parameter. This allows the pool address to be From b728963cf03d074f7c56bfc859b4d03d0798b322 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 2 Apr 2025 19:19:34 +0700 Subject: [PATCH 248/312] more parity --- script/DeployPool.s.sol | 2 +- src/EulerSwapFactory.sol | 71 ++++++++++++++++++++-------- src/interfaces/IEulerSwapFactory.sol | 70 +++++++++++++++++++-------- test/EulerSwapFactoryTest.t.sol | 24 +++++----- 4 files changed, 114 insertions(+), 53 deletions(-) diff --git a/script/DeployPool.s.sol b/script/DeployPool.s.sol index 94c47c1..5283653 100644 --- a/script/DeployPool.s.sol +++ b/script/DeployPool.s.sol @@ -57,7 +57,7 @@ contract DeployPool is ScriptUtil { evc.batch(items); vm.stopBroadcast(); - (address pool,,) = factory.getEulerAccountState(eulerAccount); + address pool = factory.poolByHolder(eulerAccount); string memory outputScriptFileName = "DeployPool_output.json"; diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 1d36bbe..bbf01cb 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -10,10 +10,10 @@ import {GenericFactory} from "evk/GenericFactory/GenericFactory.sol"; /// @custom:security-contact security@euler.xyz /// @author Euler Labs (https://www.eulerlabs.com/) contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { + /// @dev An array to store all pools addresses. + address[] private allPools; /// @dev Vaults must be deployed by this factory address public immutable evkFactory; - /// @dev An array to store all pools addresses. - address[] public allPools; /// @dev Mapping between euler account and EulerAccountState mapping(address eulerAccount => EulerAccountState state) private eulerAccountState; mapping(address asset0 => mapping(address asset1 => address[])) private poolMap; @@ -40,6 +40,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { error OldOperatorStillInstalled(); error OperatorNotInstalled(); error InvalidVaultImplementation(); + error SliceOutOfBounds(); constructor(address evc, address evkFactory_) EVCUtil(evc) { evkFactory = evkFactory_; @@ -105,36 +106,48 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { ); } + /// @inheritdoc IEulerSwapFactory function EVC() external view override(EVCUtil, IEulerSwapFactory) returns (address) { return address(evc); } /// @inheritdoc IEulerSwapFactory - function allPoolsLength() external view returns (uint256) { + function poolByHolder(address who) external view returns (address) { + return eulerAccountState[who].pool; + } + + /// @inheritdoc IEulerSwapFactory + function poolsLength() external view returns (uint256) { return allPools.length; } /// @inheritdoc IEulerSwapFactory - function getEulerAccountState(address eulerAccount) external view returns (address, uint48, uint48) { - return ( - eulerAccountState[eulerAccount].pool, - eulerAccountState[eulerAccount].allPoolsIndex, - eulerAccountState[eulerAccount].poolMapIndex - ); + function poolsSlice(uint256 start, uint256 end) external view returns (address[] memory) { + return _getSlice(allPools, start, end); } /// @inheritdoc IEulerSwapFactory - function getAllPoolsListSlice(uint256 _start, uint256 _end) external view returns (address[] memory) { - uint256 length = allPools.length; - if (_end == type(uint256).max) _end = length; - if (_end < _start || _end > length) revert InvalidQuery(); - - address[] memory allPoolsList = new address[](_end - _start); - for (uint256 i; i < _end - _start; ++i) { - allPoolsList[i] = allPools[_start + i]; - } + function pools() external view returns (address[] memory) { + return _getSlice(allPools, 0, type(uint256).max); + } + + /// @inheritdoc IEulerSwapFactory + function poolsByPairLength(address asset0, address asset1) external view returns (uint256) { + return poolMap[asset0][asset1].length; + } - return allPoolsList; + /// @inheritdoc IEulerSwapFactory + function poolsByPairSlice(address asset0, address asset1, uint256 start, uint256 end) + external + view + returns (address[] memory) + { + return _getSlice(poolMap[asset0][asset1], start, end); + } + + /// @inheritdoc IEulerSwapFactory + function poolsByPair(address asset0, address asset1) external view returns (address[] memory) { + return _getSlice(poolMap[asset0][asset1], 0, type(uint256).max); } /// @notice Validates operator authorization for euler account and update the relevant EulerAccountState. @@ -218,4 +231,24 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { function _getAssets(address pool) internal view returns (address, address) { return (EulerSwap(pool).asset0(), EulerSwap(pool).asset1()); } + + /// @notice Returns a slice of an array of addresses + /// @dev Creates a new memory array containing elements from start to end index + /// If end is type(uint256).max, it will return all elements from start to the end of the array + /// @param arr The storage array to slice + /// @param start The starting index of the slice (inclusive) + /// @param end The ending index of the slice (exclusive) + /// @return A new memory array containing the requested slice of addresses + function _getSlice(address[] storage arr, uint256 start, uint256 end) internal view returns (address[] memory) { + uint256 length = arr.length; + if (end == type(uint256).max) end = length; + if (end < start || end > length) revert SliceOutOfBounds(); + + address[] memory slice = new address[](end - start); + for (uint256 i; i < end - start; ++i) { + slice[i] = arr[start + i]; + } + + return slice; + } } diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol index 687d09a..fa7c038 100644 --- a/src/interfaces/IEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -22,15 +22,6 @@ interface IEulerSwapFactory { external returns (address); - /// @notice Retrieves the state information for a given Euler account - /// @dev Returns the current pool address, index in allPools array, and index in poolMap array - /// for the specified Euler account - /// @param eulerAccount The address of the Euler account to query - /// @return pool The address of the current pool associated with the Euler account - /// @return allPoolsIndex The index of the pool in the allPools array - /// @return poolMapIndex The index of the pool in the poolMap array for its asset pair - function getEulerAccountState(address eulerAccount) external view returns (address, uint48, uint48); - /// @notice Compute the address of a new EulerSwap pool with the given parameters /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from /// the euler account address and provided salt parameter. This allows the pool address to be @@ -44,17 +35,54 @@ interface IEulerSwapFactory { IEulerSwap.CurveParams memory curveParams, bytes32 salt ) external view returns (address); + + /// @notice Returns the address of the Ethereum Vault Connector (EVC) contract + /// @return The address of the EVC contract function EVC() external view returns (address); - /// @notice Get the length of `allPools` array. - /// @return `allPools` length. - function allPoolsLength() external view returns (uint256); - /// @notice Get the address of the pool at the given index in the `allPools` array. - /// @param index The index of the pool to retrieve. - /// @return The address of the pool at the given index. - function allPools(uint256 index) external view returns (address); - /// @notice Get a slice of the deployed pools array. - /// @param start Start index of the slice. - /// @param end End index of the slice. - /// @return An array containing the slice of the deployed pools. - function getAllPoolsListSlice(uint256 start, uint256 end) external view returns (address[] memory); + + /// @notice Returns a slice of all deployed pools + /// @dev Returns a subset of the pools array from start to end index + /// @param start The starting index of the slice (inclusive) + /// @param end The ending index of the slice (exclusive) + /// @return An array containing the requested slice of pool addresses + function poolsSlice(uint256 start, uint256 end) external view returns (address[] memory); + + /// @notice Returns all deployed pools + /// @dev Returns the complete array of all pool addresses + /// @return An array containing all pool addresses + function pools() external view returns (address[] memory); + + /// @notice Returns the number of pools for a specific asset pair + /// @dev Returns the length of the pool array for the given asset pair + /// @param asset0 The address of the first asset + /// @param asset1 The address of the second asset + /// @return The number of pools for the specified asset pair + function poolsByPairLength(address asset0, address asset1) external view returns (uint256); + + /// @notice Returns a slice of pools for a specific asset pair + /// @dev Returns a subset of the pools array for the given asset pair from start to end index + /// @param asset0 The address of the first asset + /// @param asset1 The address of the second asset + /// @param start The starting index of the slice (inclusive) + /// @param end The ending index of the slice (exclusive) + /// @return An array containing the requested slice of pool addresses for the asset pair + function poolsByPairSlice(address asset0, address asset1, uint256 start, uint256 end) external view returns (address[] memory); + + /// @notice Returns all pools for a specific asset pair + /// @dev Returns the complete array of pool addresses for the given asset pair + /// @param asset0 The address of the first asset + /// @param asset1 The address of the second asset + /// @return An array containing all pool addresses for the specified asset pair + function poolsByPair(address asset0, address asset1) external view returns (address[] memory); + + /// @notice Returns the pool address associated with a specific holder + /// @dev Returns the pool address from the EulerAccountState mapping for the given holder + /// @param who The address of the holder to query + /// @return The address of the pool associated with the holder + function poolByHolder(address who) external view returns (address); + + /// @notice Returns the total number of deployed pools + /// @dev Returns the length of the allPools array + /// @return The total number of pools deployed through the factory + function poolsLength() external view returns (uint256); } diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index 6be1db2..6240ff8 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -17,7 +17,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { } function testDeployPool() public { - uint256 allPoolsLengthBefore = eulerSwapFactory.allPoolsLength(); + uint256 allPoolsLengthBefore = eulerSwapFactory.poolsLength(); // test when new pool not set as operator @@ -61,15 +61,15 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { vm.prank(holder); evc.batch(items); - (address eulerSwap,,) = eulerSwapFactory.getEulerAccountState(holder); + address eulerSwap = eulerSwapFactory.poolByHolder(holder); - uint256 allPoolsLengthAfter = eulerSwapFactory.allPoolsLength(); + uint256 allPoolsLengthAfter = eulerSwapFactory.poolsLength(); assertEq(allPoolsLengthAfter - allPoolsLengthBefore, 1); - address[] memory poolsList = eulerSwapFactory.getAllPoolsListSlice(0, type(uint256).max); + address[] memory poolsList = eulerSwapFactory.pools(); assertEq(poolsList.length, 1); assertEq(poolsList[0], eulerSwap); - assertEq(eulerSwapFactory.allPools(0), address(eulerSwap)); + assertEq(poolsList[0], address(eulerSwap)); // test when deploying second pool while old pool is still set as operator @@ -93,7 +93,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { evc.batch(items); // test deploying new pool for same assets pair as old one - (address oldPool,,) = eulerSwapFactory.getEulerAccountState(holder); + address oldPool = eulerSwapFactory.poolByHolder(holder); salt = bytes32(uint256(123456)); predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); @@ -120,11 +120,11 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { vm.prank(holder); evc.batch(items); - (address pool,,) = eulerSwapFactory.getEulerAccountState(holder); + address pool = eulerSwapFactory.poolByHolder(holder); assertEq(pool, predictedAddress); // test deploying new pool for different assets pair as old one - (oldPool,,) = eulerSwapFactory.getEulerAccountState(holder); + oldPool = eulerSwapFactory.poolByHolder(holder); poolParams = IEulerSwap.Params(address(eTST), address(eTST3), holder, 1e18, 1e18, 1e18, 1e18, 0); salt = bytes32(uint256(1234567)); @@ -153,13 +153,13 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { vm.prank(holder); evc.batch(items); - (pool,,) = eulerSwapFactory.getEulerAccountState(holder); + pool = eulerSwapFactory.poolByHolder(holder); assertEq(pool, predictedAddress); } - function testInvalidGetAllPoolsListSliceQuery() public { - vm.expectRevert(EulerSwapFactory.InvalidQuery.selector); - eulerSwapFactory.getAllPoolsListSlice(1, 0); + function testInvalidPoolsSliceQuery() public { + vm.expectRevert(EulerSwapFactory.SliceOutOfBounds.selector); + eulerSwapFactory.poolsSlice(1, 0); } function testDeployWithAssetsOutOfOrderOrEqual() public { From e5c722b8afac9551e6f79ca4b37fff26cd6e04cf Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Wed, 2 Apr 2025 19:27:26 +0700 Subject: [PATCH 249/312] more tests for 100% coverage --- src/interfaces/IEulerSwapFactory.sol | 5 +- test/EulerSwapFactoryTest.t.sol | 87 +++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol index fa7c038..06cba33 100644 --- a/src/interfaces/IEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -66,7 +66,10 @@ interface IEulerSwapFactory { /// @param start The starting index of the slice (inclusive) /// @param end The ending index of the slice (exclusive) /// @return An array containing the requested slice of pool addresses for the asset pair - function poolsByPairSlice(address asset0, address asset1, uint256 start, uint256 end) external view returns (address[] memory); + function poolsByPairSlice(address asset0, address asset1, uint256 start, uint256 end) + external + view + returns (address[] memory); /// @notice Returns all pools for a specific asset pair /// @dev Returns the complete array of pool addresses for the given asset pair diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index 6240ff8..d917ffc 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -14,6 +14,8 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { vm.prank(creator); eulerSwapFactory = new EulerSwapFactory(address(evc), address(factory)); + + assertEq(eulerSwapFactory.EVC(), address(evc)); } function testDeployPool() public { @@ -157,11 +159,39 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { assertEq(pool, predictedAddress); } - function testInvalidPoolsSliceQuery() public { + function testInvalidPoolsSliceOutOfBounds() public { vm.expectRevert(EulerSwapFactory.SliceOutOfBounds.selector); eulerSwapFactory.poolsSlice(1, 0); } + function testDeployWithInvalidVaultImplementation() public { + bytes32 salt = bytes32(uint256(1234)); + IEulerSwap.Params memory poolParams = + IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 0); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); + + // Create a fake vault that's not deployed by the factory + address fakeVault = address(0x1234); + poolParams.vault0 = fakeVault; + poolParams.vault1 = address(eTST2); + + vm.prank(holder); + vm.expectRevert(EulerSwapFactory.InvalidVaultImplementation.selector); + eulerSwapFactory.deployPool(poolParams, curveParams, salt); + } + + function testDeployWithUnauthorizedCaller() public { + bytes32 salt = bytes32(uint256(1234)); + IEulerSwap.Params memory poolParams = + IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 0); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); + + // Call from a different address than the euler account + vm.prank(address(0x1234)); + vm.expectRevert(EulerSwapFactory.Unauthorized.selector); + eulerSwapFactory.deployPool(poolParams, curveParams, salt); + } + function testDeployWithAssetsOutOfOrderOrEqual() public { bytes32 salt = bytes32(uint256(1234)); IEulerSwap.Params memory poolParams = @@ -184,6 +214,61 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { eulerSwapFactory.deployPool(poolParams, curveParams, salt); } + function testPoolsByPair() public { + // First deploy a pool + bytes32 salt = bytes32(uint256(1234)); + IEulerSwap.Params memory poolParams = + IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 0); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); + + address predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); + + IEVC.BatchItem[] memory items = new IEVC.BatchItem[](2); + items[0] = IEVC.BatchItem({ + onBehalfOfAccount: address(0), + targetContract: address(evc), + value: 0, + data: abi.encodeCall(evc.setAccountOperator, (holder, predictedAddress, true)) + }); + items[1] = IEVC.BatchItem({ + onBehalfOfAccount: holder, + targetContract: address(eulerSwapFactory), + value: 0, + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) + }); + + vm.prank(holder); + evc.batch(items); + + // Get the deployed pool and its assets + address pool = eulerSwapFactory.poolByHolder(holder); + address asset0 = EulerSwap(pool).asset0(); + address asset1 = EulerSwap(pool).asset1(); + + // Test poolsByPairLength + assertEq(eulerSwapFactory.poolsByPairLength(asset0, asset1), 1); + + // Test poolsByPairSlice + address[] memory slice = eulerSwapFactory.poolsByPairSlice(asset0, asset1, 0, 1); + assertEq(slice.length, 1); + assertEq(slice[0], predictedAddress); + + // Test poolsByPair + address[] memory pools = eulerSwapFactory.poolsByPair(asset0, asset1); + assertEq(pools.length, 1); + assertEq(pools[0], predictedAddress); + } + + function testComputePoolAddress() public view { + bytes32 salt = bytes32(uint256(1234)); + IEulerSwap.Params memory poolParams = + IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 0); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); + + address predictedAddress = eulerSwapFactory.computePoolAddress(poolParams, curveParams, salt); + assertEq(predictedAddress, predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt)); + } + function predictPoolAddress( address factoryAddress, IEulerSwap.Params memory poolParams, From 31923d55ea40145db07fefd546a75659c820527d Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 3 Apr 2025 15:46:17 +0700 Subject: [PATCH 250/312] update --- script/DeployPool.s.sol | 2 +- src/EulerSwapFactory.sol | 91 ++++++++++++---------------- src/interfaces/IEulerSwapFactory.sol | 8 ++- test/EulerSwapFactoryTest.t.sol | 12 ++-- 4 files changed, 52 insertions(+), 61 deletions(-) diff --git a/script/DeployPool.s.sol b/script/DeployPool.s.sol index 5283653..63da318 100644 --- a/script/DeployPool.s.sol +++ b/script/DeployPool.s.sol @@ -57,7 +57,7 @@ contract DeployPool is ScriptUtil { evc.batch(items); vm.stopBroadcast(); - address pool = factory.poolByHolder(eulerAccount); + address pool = factory.poolByEulerAccount(eulerAccount); string memory outputScriptFileName = "DeployPool_output.json"; diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index bbf01cb..aee562d 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -57,9 +57,11 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { InvalidVaultImplementation() ); + uninstall(params.eulerAccount); + EulerSwap pool = new EulerSwap{salt: keccak256(abi.encode(params.eulerAccount, salt))}(params, curveParams); - checkAndUpdateEulerAccountState(params.eulerAccount, address(pool)); + updateEulerAccountState(params.eulerAccount, address(pool)); EulerSwap(pool).activate(); @@ -82,6 +84,11 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { return address(pool); } + /// @inheritdoc IEulerSwapFactory + function uninstallPool() external { + uninstall(_msgSender()); + } + /// @inheritdoc IEulerSwapFactory function computePoolAddress( IEulerSwap.Params memory poolParams, @@ -112,7 +119,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { } /// @inheritdoc IEulerSwapFactory - function poolByHolder(address who) external view returns (address) { + function poolByEulerAccount(address who) external view returns (address) { return eulerAccountState[who].pool; } @@ -153,73 +160,51 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { /// @notice Validates operator authorization for euler account and update the relevant EulerAccountState. /// @param eulerAccount The address of the euler account. /// @param newOperator The address of the new pool. - function checkAndUpdateEulerAccountState(address eulerAccount, address newOperator) internal { + function updateEulerAccountState(address eulerAccount, address newOperator) internal { require(evc.isAccountOperatorAuthorized(eulerAccount, newOperator), OperatorNotInstalled()); - (address newOpAsset0, address newOpAsset1) = _getAssets(newOperator); - address oldOperator = eulerAccountState[eulerAccount].pool; - - if (oldOperator != address(0)) { - require(!evc.isAccountOperatorAuthorized(eulerAccount, oldOperator), OldOperatorStillInstalled()); + (address asset0, address asset1) = _getAssets(newOperator); - // replace pool address in allPools array - _updateInArray(allPools, eulerAccountState[eulerAccount].allPoolsIndex, newOperator); + address[] storage poolMapArray = poolMap[asset0][asset1]; - eulerAccountState[eulerAccount].pool = newOperator; + eulerAccountState[eulerAccount] = EulerAccountState({ + pool: newOperator, + allPoolsIndex: uint48(allPools.length), + poolMapIndex: uint48(poolMapArray.length) + }); - (address oldOpAsset0, address oldOpAsset1) = _getAssets(oldOperator); + allPools.push(newOperator); + poolMapArray.push(newOperator); + } - // if deploying new pool for same assets pair, just update poolMap without pop() - // else, we need to go the traditional path, reduce the array size, update eulerAccount poolMapIndex and push new one - if (oldOpAsset0 == newOpAsset0 && oldOpAsset1 == newOpAsset1) { - _updateInArray( - poolMap[newOpAsset0][newOpAsset1], eulerAccountState[eulerAccount].poolMapIndex, newOperator - ); - } else { - _removeFromArray(poolMap[oldOpAsset0][oldOpAsset1], eulerAccountState[eulerAccount].poolMapIndex); + /// @notice Uninstalls the pool associated with the given Euler account + /// @dev This function removes the pool from the factory's tracking and emits a PoolUninstalled event + /// @dev The function checks if the operator is still installed and reverts if it is + /// @dev If no pool exists for the account, the function returns without any action + /// @param eulerAccount The address of the Euler account whose pool should be uninstalled + function uninstall(address eulerAccount) internal { + address pool = eulerAccountState[eulerAccount].pool; - eulerAccountState[eulerAccount].poolMapIndex = uint48(poolMap[newOpAsset0][newOpAsset1].length); + if (pool == address(0)) return; - _pushInArray(poolMap[newOpAsset0][newOpAsset1], newOperator); - } + require(!evc.isAccountOperatorAuthorized(eulerAccount, pool), OldOperatorStillInstalled()); - emit PoolUninstalled(oldOpAsset0, oldOpAsset1, eulerAccount, oldOperator); - } else { - address[] storage poolMapArray = poolMap[newOpAsset0][newOpAsset1]; + (address asset0, address asset1) = _getAssets(pool); - eulerAccountState[eulerAccount] = EulerAccountState({ - pool: newOperator, - allPoolsIndex: uint48(allPools.length), - poolMapIndex: uint48(poolMapArray.length) - }); + address[] storage poolMapArr = poolMap[asset0][asset1]; - _pushInArray(allPools, newOperator); - _pushInArray(poolMapArray, newOperator); - } - } + swapAndPop(allPools, eulerAccountState[eulerAccount].allPoolsIndex); + swapAndPop(poolMapArr, eulerAccountState[eulerAccount].poolMapIndex); - /// @notice Updates an element at a specific index in an array - /// @dev Directly modifies the array element at the given index with a new value - /// @param arr The storage array to update - /// @param index The index of the element to update - /// @param _newValue The new value to set at the specified index - function _updateInArray(address[] storage arr, uint256 index, address _newValue) internal { - arr[index] = _newValue; - } + delete eulerAccountState[eulerAccount]; - /// @notice Adds a new element to the end of an array - /// @dev Uses the push operation to append a new value to the array - /// @param arr The storage array to append to - /// @param _newValue The new value to append to the array - function _pushInArray(address[] storage arr, address _newValue) internal { - arr.push(_newValue); + emit PoolUninstalled(asset0, asset1, eulerAccount, pool); } - /// @notice Removes an element from an array at a specific index - /// @dev Uses the swap-and-pop pattern to remove an element while maintaining array order - /// @param arr The storage array to remove from + /// @notice Swaps the element at the given index with the last element and removes the last element + /// @param arr The storage array to modify /// @param index The index of the element to remove - function _removeFromArray(address[] storage arr, uint256 index) internal { + function swapAndPop(address[] storage arr, uint256 index) internal { arr[index] = arr[arr.length - 1]; arr.pop(); } diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol index 06cba33..50b141b 100644 --- a/src/interfaces/IEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -22,6 +22,12 @@ interface IEulerSwapFactory { external returns (address); + /// @notice Uninstalls the pool associated with the Euler account + /// @dev This function removes the pool from the factory's tracking and emits a PoolUninstalled event + /// @dev The function can only be called by the Euler account that owns the pool + /// @dev If no pool is installed for the caller, the function returns without any action + function uninstallPool() external; + /// @notice Compute the address of a new EulerSwap pool with the given parameters /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from /// the euler account address and provided salt parameter. This allows the pool address to be @@ -82,7 +88,7 @@ interface IEulerSwapFactory { /// @dev Returns the pool address from the EulerAccountState mapping for the given holder /// @param who The address of the holder to query /// @return The address of the pool associated with the holder - function poolByHolder(address who) external view returns (address); + function poolByEulerAccount(address who) external view returns (address); /// @notice Returns the total number of deployed pools /// @dev Returns the length of the allPools array diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index d917ffc..ea2963a 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -63,7 +63,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { vm.prank(holder); evc.batch(items); - address eulerSwap = eulerSwapFactory.poolByHolder(holder); + address eulerSwap = eulerSwapFactory.poolByEulerAccount(holder); uint256 allPoolsLengthAfter = eulerSwapFactory.poolsLength(); assertEq(allPoolsLengthAfter - allPoolsLengthBefore, 1); @@ -95,7 +95,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { evc.batch(items); // test deploying new pool for same assets pair as old one - address oldPool = eulerSwapFactory.poolByHolder(holder); + address oldPool = eulerSwapFactory.poolByEulerAccount(holder); salt = bytes32(uint256(123456)); predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); @@ -122,11 +122,11 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { vm.prank(holder); evc.batch(items); - address pool = eulerSwapFactory.poolByHolder(holder); + address pool = eulerSwapFactory.poolByEulerAccount(holder); assertEq(pool, predictedAddress); // test deploying new pool for different assets pair as old one - oldPool = eulerSwapFactory.poolByHolder(holder); + oldPool = eulerSwapFactory.poolByEulerAccount(holder); poolParams = IEulerSwap.Params(address(eTST), address(eTST3), holder, 1e18, 1e18, 1e18, 1e18, 0); salt = bytes32(uint256(1234567)); @@ -155,7 +155,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { vm.prank(holder); evc.batch(items); - pool = eulerSwapFactory.poolByHolder(holder); + pool = eulerSwapFactory.poolByEulerAccount(holder); assertEq(pool, predictedAddress); } @@ -241,7 +241,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { evc.batch(items); // Get the deployed pool and its assets - address pool = eulerSwapFactory.poolByHolder(holder); + address pool = eulerSwapFactory.poolByEulerAccount(holder); address asset0 = EulerSwap(pool).asset0(); address asset1 = EulerSwap(pool).asset1(); From 136eaccebc3c5c47e7f2bcb06f06c1bf85276385 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 3 Apr 2025 15:51:00 +0700 Subject: [PATCH 251/312] clean --- src/EulerSwapFactory.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index aee562d..e2745db 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -119,8 +119,8 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { } /// @inheritdoc IEulerSwapFactory - function poolByEulerAccount(address who) external view returns (address) { - return eulerAccountState[who].pool; + function poolByEulerAccount(address eulerAccount) external view returns (address) { + return eulerAccountState[eulerAccount].pool; } /// @inheritdoc IEulerSwapFactory From efe5487bdb353ad5e2d1a1262be7b92838ab0ec7 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 31 Mar 2025 20:36:05 -0400 Subject: [PATCH 252/312] alternate approach for protocol fee collection --- src/EulerSwap.sol | 31 ++++++++++++++++++++++--------- test/Fees.t.sol | 12 ++++++++---- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index d3e8cb4..64d0518 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -16,6 +16,9 @@ contract EulerSwap is IEulerSwap, EVCUtil { bytes32 public constant curve = bytes32("EulerSwap v1"); + uint256 public constant protocolFee = 0.1e18; + address public constant protocolFeeRecipient = address(0); + address public immutable vault0; address public immutable vault1; address public immutable asset0; @@ -24,6 +27,8 @@ contract EulerSwap is IEulerSwap, EVCUtil { uint112 public immutable equilibriumReserve0; uint112 public immutable equilibriumReserve1; uint256 public immutable feeMultiplier; + uint256 private immutable feeMultiplierProtocol; + uint256 private immutable feeMultiplierLP; uint256 public immutable priceX; uint256 public immutable priceY; @@ -84,6 +89,8 @@ contract EulerSwap is IEulerSwap, EVCUtil { reserve0 = params.currReserve0; reserve1 = params.currReserve1; feeMultiplier = 1e18 - params.fee; + feeMultiplierProtocol = 1e18 - (params.fee * protocolFee / 1e18); + feeMultiplierLP = feeMultiplier * 1e18 / feeMultiplierProtocol; // Curve params @@ -120,11 +127,8 @@ contract EulerSwap is IEulerSwap, EVCUtil { // Deposit all available funds, adjust received amounts downward to collect fees - uint256 amount0In = IERC20(asset0).balanceOf(address(this)); - if (amount0In > 0) amount0In = depositAssets(vault0, amount0In) * feeMultiplier / 1e18; - - uint256 amount1In = IERC20(asset1).balanceOf(address(this)); - if (amount1In > 0) amount1In = depositAssets(vault1, amount1In) * feeMultiplier / 1e18; + uint256 amount0In = depositAssets(asset0, vault0); + uint256 amount1In = depositAssets(asset1, vault1); // Verify curve invariant is satisfied @@ -211,14 +215,23 @@ contract EulerSwap is IEulerSwap, EVCUtil { } /// @notice Deposits assets into a vault and automatically repays any outstanding debt + /// @param asset The address of the underlying asset /// @param vault The address of the vault to deposit into - /// @param amount The amount of assets to deposit /// @return The amount of assets successfully deposited /// @dev This function attempts to deposit assets into the specified vault. /// @dev If the deposit fails with E_ZeroShares error, it safely returns 0 (this happens with very small amounts). /// @dev After successful deposit, if the user has any outstanding controller-enabled debt, it attempts to repay it. /// @dev If all debt is repaid, the controller is automatically disabled to reduce gas costs in future operations. - function depositAssets(address vault, uint256 amount) internal returns (uint256) { + function depositAssets(address asset, address vault) internal returns (uint256) { + uint256 amount = IERC20(asset).balanceOf(address(this)); + if (amount == 0) return 0; + + { + uint256 feeAmount = amount - (amount * feeMultiplierProtocol / 1e18); + IERC20(asset).transfer(protocolFeeRecipient, feeAmount); + amount -= feeAmount; + } + uint256 deposited; if (IEVC(evc).isControllerEnabled(eulerAccount, vault)) { @@ -238,13 +251,13 @@ contract EulerSwap is IEulerSwap, EVCUtil { try IEVault(vault).deposit(amount, eulerAccount) {} catch (bytes memory reason) { require(bytes4(reason) == EVKErrors.E_ZeroShares.selector, DepositFailure(reason)); - return deposited; + amount = 0; } deposited += amount; } - return deposited; + return (deposited * feeMultiplierLP + (1e18 - 1)) / 1e18; } /// @notice Approves tokens for a given vault, supporting both standard approvals and permit2 diff --git a/test/Fees.t.sol b/test/Fees.t.sol index dc3c753..34c91ce 100644 --- a/test/Fees.t.sol +++ b/test/Fees.t.sol @@ -58,8 +58,10 @@ contract FeesTest is EulerSwapTestBase { // Holder's NAV increased by fee amount, plus slightly extra because we are not at curve equilibrium point - assertGt(getHolderNAV(), origNav + int256(amountIn - amountInNoFees)); - assertEq(eTST.balanceOf(address(holder)), 10e18 + amountIn); + uint256 protocolFeesCollected = assetTST.balanceOf(address(0)); + + assertGt(getHolderNAV() + int256(protocolFeesCollected), origNav + int256(amountIn - amountInNoFees)); + assertEq(eTST.balanceOf(address(holder)), 10e18 + amountIn - protocolFeesCollected); assertEq(eTST2.balanceOf(address(holder)), 10e18 - amountOut); } @@ -107,8 +109,10 @@ contract FeesTest is EulerSwapTestBase { // Holder's NAV increased by fee amount, plus slightly extra because we are not at curve equilibrium point - assertGt(getHolderNAV(), origNav + int256(amountIn - amountInNoFees)); - assertEq(eTST.balanceOf(address(holder)), 10e18 + amountIn); + uint256 protocolFeesCollected = assetTST.balanceOf(address(0)); + + assertGt(getHolderNAV() + int256(protocolFeesCollected), origNav + int256(amountIn - amountInNoFees)); + assertEq(eTST.balanceOf(address(holder)), 10e18 + amountIn - protocolFeesCollected); assertEq(eTST2.balanceOf(address(holder)), 10e18 - amountOut); } } From 18b91658ff890dc85e56f467824fc8c6016b0170 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Thu, 3 Apr 2025 15:00:50 -0400 Subject: [PATCH 253/312] improve and simplify fee split calculation, change feeMultiplier to just fee --- src/EulerSwap.sol | 29 ++++++++++++++++------------- src/EulerSwapFactory.sol | 4 ++-- src/EulerSwapPeriphery.sol | 10 +++++----- src/interfaces/IEulerSwap.sol | 4 +++- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 64d0518..567f445 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -16,9 +16,6 @@ contract EulerSwap is IEulerSwap, EVCUtil { bytes32 public constant curve = bytes32("EulerSwap v1"); - uint256 public constant protocolFee = 0.1e18; - address public constant protocolFeeRecipient = address(0); - address public immutable vault0; address public immutable vault1; address public immutable asset0; @@ -26,9 +23,9 @@ contract EulerSwap is IEulerSwap, EVCUtil { address public immutable eulerAccount; uint112 public immutable equilibriumReserve0; uint112 public immutable equilibriumReserve1; - uint256 public immutable feeMultiplier; - uint256 private immutable feeMultiplierProtocol; - uint256 private immutable feeMultiplierLP; + uint256 public immutable fee; + uint256 public immutable protocolFee; + address public immutable protocolFeeRecipient; uint256 public immutable priceX; uint256 public immutable priceY; @@ -88,9 +85,9 @@ contract EulerSwap is IEulerSwap, EVCUtil { equilibriumReserve1 = params.equilibriumReserve1; reserve0 = params.currReserve0; reserve1 = params.currReserve1; - feeMultiplier = 1e18 - params.fee; - feeMultiplierProtocol = 1e18 - (params.fee * protocolFee / 1e18); - feeMultiplierLP = feeMultiplier * 1e18 / feeMultiplierProtocol; + fee = params.fee; + protocolFee = 0.1e18; + protocolFeeRecipient = address(0); // Curve params @@ -226,10 +223,16 @@ contract EulerSwap is IEulerSwap, EVCUtil { uint256 amount = IERC20(asset).balanceOf(address(this)); if (amount == 0) return 0; + uint256 feeAmount = amount * fee / 1e18; + { - uint256 feeAmount = amount - (amount * feeMultiplierProtocol / 1e18); - IERC20(asset).transfer(protocolFeeRecipient, feeAmount); - amount -= feeAmount; + uint256 protocolFeeAmount = feeAmount * protocolFee / 1e18; + + if (protocolFeeAmount != 0) { + IERC20(asset).transfer(protocolFeeRecipient, protocolFeeAmount); + amount -= protocolFeeAmount; + feeAmount -= protocolFeeAmount; + } } uint256 deposited; @@ -257,7 +260,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { deposited += amount; } - return (deposited * feeMultiplierLP + (1e18 - 1)) / 1e18; + return deposited > feeAmount ? deposited - feeAmount : 0; } /// @notice Approves tokens for a given vault, supporting both standard approvals and permit2 diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index e2745db..ebdfb1e 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -23,7 +23,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { address indexed asset1, address vault0, address vault1, - uint256 indexed feeMultiplier, + uint256 indexed fee, address eulerAccount, uint256 reserve0, uint256 reserve1, @@ -70,7 +70,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { pool.asset1(), params.vault0, params.vault1, - pool.feeMultiplier(), + pool.fee(), params.eulerAccount, params.currReserve0, params.currReserve1, diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index 2983e7e..63f988c 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -105,11 +105,11 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { ); require(amount <= type(uint112).max, SwapLimitExceeded()); - uint256 feeMultiplier = eulerSwap.feeMultiplier(); + uint256 fee = eulerSwap.fee(); (uint112 reserve0, uint112 reserve1,) = eulerSwap.getReserves(); - // exactIn: decrease received amountIn, rounding down - if (exactIn) amount = amount * feeMultiplier / 1e18; + // exactIn: decrease effective amountIn + if (exactIn) amount = amount - (amount * fee / 1e18); bool asset0IsInput = checkTokens(eulerSwap, tokenIn, tokenOut); (uint256 inLimit, uint256 outLimit) = calcLimits(eulerSwap, asset0IsInput); @@ -124,8 +124,8 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { require(amount <= outLimit && quote <= inLimit, SwapLimitExceeded()); } - // exactOut: increase required quote(amountIn), rounding up - if (!exactIn) quote = (quote * 1e18 + (feeMultiplier - 1)) / feeMultiplier; + // exactOut: inflate required amountIn + if (!exactIn) quote = (quote * 1e18) / (1e18 - fee); return quote; } diff --git a/src/interfaces/IEulerSwap.sol b/src/interfaces/IEulerSwap.sol index dd192ec..9adfbdc 100644 --- a/src/interfaces/IEulerSwap.sol +++ b/src/interfaces/IEulerSwap.sol @@ -50,7 +50,9 @@ interface IEulerSwap { function eulerAccount() external view returns (address); function equilibriumReserve0() external view returns (uint112); function equilibriumReserve1() external view returns (uint112); - function feeMultiplier() external view returns (uint256); + function fee() external view returns (uint256); + function protocolFee() external view returns (uint256); + function protocolFeeRecipient() external view returns (address); /// @notice Returns the current reserves of the pool /// @return reserve0 The amount of asset0 in the pool /// @return reserve1 The amount of asset1 in the pool From e7776c005a042e686241a66e1e4c64e1e2a712d2 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Thu, 3 Apr 2025 15:57:10 -0400 Subject: [PATCH 254/312] fix conflicts with new fee computation method --- src/EulerSwapFactory.sol | 2 +- src/EulerSwapHook.sol | 10 +++--- test/EulerSwapFactoryTest.t.sol | 64 --------------------------------- test/EulerSwapHook.fees.t.sol | 4 +-- 4 files changed, 8 insertions(+), 72 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 5814a9b..1338a04 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -221,7 +221,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { /// @param pool The address of the pool to query /// @return The addresses of asset0 and asset1 in the pool function _getAssets(address pool) internal view returns (address, address) { - return (EulerSwap(pool).asset0(), EulerSwap(pool).asset1()); + return (IEulerSwap(pool).asset0(), IEulerSwap(pool).asset1()); } /// @notice Returns a slice of an array of addresses diff --git a/src/EulerSwapHook.sol b/src/EulerSwapHook.sol index ef40683..d2a019f 100644 --- a/src/EulerSwapHook.sol +++ b/src/EulerSwapHook.sol @@ -86,7 +86,7 @@ contract EulerSwapHook is EulerSwap, BaseHook { // the debt will be paid by the swapper via the swap router // TODO: can we optimize the transfer by pulling from PoolManager directly to Euler? poolManager.take(inputCurrency, address(this), amountIn); - amountInWithoutFee = depositAssets(zeroForOne ? vault0 : vault1, amountIn) * feeMultiplier / 1e18; + amountInWithoutFee = depositAssets(zeroForOne ? asset0 : asset1, zeroForOne ? vault0 : vault1); // pay the output token, to the PoolManager from an Euler vault // the credit will be forwarded to the swap router, which then forwards it to the swapper @@ -120,8 +120,8 @@ contract EulerSwapHook is EulerSwap, BaseHook { require(evc.isAccountOperatorAuthorized(eulerAccount, address(this)), OperatorNotInstalled()); require(amount <= type(uint112).max, SwapLimitExceeded()); - // exactIn: decrease received amountIn, rounding down - if (exactIn) amount = amount * feeMultiplier / 1e18; + // exactIn: decrease effective amountIn + if (exactIn) amount = amount - (amount * fee / 1e18); (uint256 inLimit, uint256 outLimit) = calcLimits(asset0IsInput); @@ -135,8 +135,8 @@ contract EulerSwapHook is EulerSwap, BaseHook { require(amount <= outLimit && quote <= inLimit, SwapLimitExceeded()); } - // exactOut: increase required quote(amountIn), rounding up - if (!exactIn) quote = (quote * 1e18 + (feeMultiplier - 1)) / feeMultiplier; + // exactOut: inflate required amountIn + if (!exactIn) quote = (quote * 1e18) / (1e18 - fee); return quote; } diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index fb57792..ee8dda3 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -103,70 +103,6 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { vm.prank(holder); vm.expectRevert(EulerSwapFactory.OldOperatorStillInstalled.selector); evc.batch(items); - - // test deploying new pool for same assets pair as old one - address oldPool = eulerSwapFactory.poolByEulerAccount(holder); - salt = bytes32(uint256(123456)); - predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); - - items = new IEVC.BatchItem[](3); - items[0] = IEVC.BatchItem({ - onBehalfOfAccount: address(0), - targetContract: address(evc), - value: 0, - data: abi.encodeCall(evc.setAccountOperator, (holder, oldPool, false)) - }); - items[1] = IEVC.BatchItem({ - onBehalfOfAccount: address(0), - targetContract: address(evc), - value: 0, - data: abi.encodeCall(evc.setAccountOperator, (holder, predictedAddress, true)) - }); - items[2] = IEVC.BatchItem({ - onBehalfOfAccount: holder, - targetContract: address(eulerSwapFactory), - value: 0, - data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) - }); - - vm.prank(holder); - evc.batch(items); - - address pool = eulerSwapFactory.poolByEulerAccount(holder); - assertEq(pool, predictedAddress); - - // test deploying new pool for different assets pair as old one - oldPool = eulerSwapFactory.poolByEulerAccount(holder); - poolParams = IEulerSwap.Params(address(eTST), address(eTST3), holder, 1e18, 1e18, 1e18, 1e18, 0); - - salt = bytes32(uint256(1234567)); - predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); - - items = new IEVC.BatchItem[](3); - items[0] = IEVC.BatchItem({ - onBehalfOfAccount: address(0), - targetContract: address(evc), - value: 0, - data: abi.encodeCall(evc.setAccountOperator, (holder, oldPool, false)) - }); - items[1] = IEVC.BatchItem({ - onBehalfOfAccount: address(0), - targetContract: address(evc), - value: 0, - data: abi.encodeCall(evc.setAccountOperator, (holder, predictedAddress, true)) - }); - items[2] = IEVC.BatchItem({ - onBehalfOfAccount: holder, - targetContract: address(eulerSwapFactory), - value: 0, - data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) - }); - - vm.prank(holder); - evc.batch(items); - - pool = eulerSwapFactory.poolByEulerAccount(holder); - assertEq(pool, predictedAddress); } function testInvalidPoolsSliceOutOfBounds() public { diff --git a/test/EulerSwapHook.fees.t.sol b/test/EulerSwapHook.fees.t.sol index f91bbae..71d49b3 100644 --- a/test/EulerSwapHook.fees.t.sol +++ b/test/EulerSwapHook.fees.t.sol @@ -47,7 +47,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { (uint112 r0, uint112 r1,) = eulerSwap.getReserves(); uint256 amountIn = 1e18; - uint256 amountInWithoutFee = amountIn * eulerSwap.feeMultiplier() / 1e18; + uint256 amountInWithoutFee = amountIn - (amountIn * eulerSwap.fee() / 1e18); uint256 amountOut = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); @@ -89,7 +89,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); // inverse of the fee math in Periphery - uint256 amountInWithoutFee = (amountIn * eulerSwap.feeMultiplier() - eulerSwap.feeMultiplier()) / 1e18; + uint256 amountInWithoutFee = amountIn * (1e18 - eulerSwap.fee()) / 1e18; assetTST.mint(anyone, amountIn); From d20ca38ad1620a09a42fd41fe2fdfbcf713f7efd Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 7 Apr 2025 07:43:41 -0400 Subject: [PATCH 255/312] import Michael's search() routine and dependencies --- src/EulerSwapPeriphery.sol | 228 ++++++++++++++++++++++++++----------- 1 file changed, 163 insertions(+), 65 deletions(-) diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index 63f988c..3c3bf90 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -114,7 +114,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { bool asset0IsInput = checkTokens(eulerSwap, tokenIn, tokenOut); (uint256 inLimit, uint256 outLimit) = calcLimits(eulerSwap, asset0IsInput); - uint256 quote = binarySearch(eulerSwap, reserve0, reserve1, amount, exactIn, asset0IsInput); + uint256 quote = search(eulerSwap, reserve0, reserve1, amount, exactIn, asset0IsInput); if (exactIn) { // if `exactIn`, `quote` is the amount of assets to buy from the AMM @@ -130,70 +130,6 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { return quote; } - /// @notice Binary searches for the output amount along a swap curve given input parameters - /// @dev General-purpose routine for binary searching swapping curves. - /// Although some curves may have more efficient closed-form solutions, - /// this works with any monotonic curve. - /// @param eulerSwap The EulerSwap contract to search the curve for - /// @param reserve0 Current reserve of asset0 in the pool - /// @param reserve1 Current reserve of asset1 in the pool - /// @param amount The input or output amount depending on exactIn - /// @param exactIn True if amount is input amount, false if amount is output amount - /// @param asset0IsInput True if asset0 is being input, false if asset1 is being input - /// @return output The calculated output amount from the binary search - function binarySearch( - IEulerSwap eulerSwap, - uint112 reserve0, - uint112 reserve1, - uint256 amount, - bool exactIn, - bool asset0IsInput - ) internal view returns (uint256 output) { - int256 dx; - int256 dy; - - if (exactIn) { - if (asset0IsInput) dx = int256(amount); - else dy = int256(amount); - } else { - if (asset0IsInput) dy = -int256(amount); - else dx = -int256(amount); - } - - unchecked { - int256 reserve0New = int256(uint256(reserve0)) + dx; - int256 reserve1New = int256(uint256(reserve1)) + dy; - require(reserve0New > 0 && reserve1New > 0, SwapLimitExceeded()); - - uint256 low; - uint256 high = type(uint112).max; - - while (low < high) { - uint256 mid = (low + high) / 2; - require(mid > 0, SwapLimitExceeded()); - (uint256 a, uint256 b) = dy == 0 ? (uint256(reserve0New), mid) : (mid, uint256(reserve1New)); - if (eulerSwap.verify(a, b)) { - high = mid; - } else { - low = mid + 1; - } - } - - require(high < type(uint112).max, SwapLimitExceeded()); // at least one point verified - - if (dx != 0) dy = int256(low) - reserve1New; - else dx = int256(low) - reserve0New; - } - - if (exactIn) { - if (asset0IsInput) output = uint256(-dy); - else output = uint256(-dx); - } else { - if (asset0IsInput) output = dx >= 0 ? uint256(dx) : 0; - else output = dy >= 0 ? uint256(dy) : 0; - } - } - /** * @notice Calculates the maximum input and output amounts for a swap based on protocol constraints * @dev Determines limits by checking multiple factors: @@ -288,4 +224,166 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; else revert UnsupportedPair(); } + + + + + ////////////////////////////// + + + // Exact version starts here. + // Strategy is to re-calculate everything using f() and fInverse() and see where things break. + function search( + IEulerSwap eulerSwap, + uint112 reserve0, + uint112 reserve1, + uint256 amount, + bool exactIn, + bool asset0IsInput + ) internal view returns (uint256 output) { + uint256 px = eulerSwap.priceX(); + uint256 py = eulerSwap.priceY(); + uint256 x0 = eulerSwap.equilibriumReserve0(); + uint256 y0 = eulerSwap.equilibriumReserve1(); + uint256 cx = eulerSwap.concentrationX(); + uint256 cy = eulerSwap.concentrationY(); + + uint256 xNew; + uint256 yNew; + + if (exactIn) { + // exact in + if (asset0IsInput) { + // swap X in and Y out + xNew = reserve0 + amount; + if (xNew < x0) { + // remain on f() + yNew = f(xNew, px, py, x0, y0, cx); + } else { + // move to g() + yNew = fInverse(xNew, py, px, y0, x0, cy); + } + output = reserve1 > yNew ? reserve1 - yNew : 0; + } else { + // swap Y in and X out + yNew = reserve1 + amount; + if (yNew < y0) { + // remain on g() + xNew = f(yNew, py, px, y0, x0, cy); + } else { + // move to f() + xNew = fInverse(yNew, px, py, x0, y0, cx); + } + output = reserve0 > xNew ? reserve0 - xNew : 0; + } + } else { + // exact out + if (asset0IsInput) { + // swap Y out and X in + yNew = reserve1 - amount; + if (yNew < y0) { + // remain on g() + xNew = f(yNew, py, px, y0, x0, cy); + } else { + // move to f() + xNew = fInverse(yNew, px, py, x0, y0, cx); + } + output = xNew > reserve0 ? xNew - reserve0 : 0; + } else { + // swap X out and Y in + xNew = reserve0 - amount; + if (xNew < x0) { + // remain on f() + yNew = f(xNew, py, px, y0, x0, cx); + } else { + // move to g() + yNew = fInverse(xNew, py, px, y0, x0, cy); + } + output = yNew > reserve1 ? yNew - reserve1 : 0; + } + } + } + + /// @dev EulerSwap curve definition + /// Pre-conditions: x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 + function f(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { + unchecked { + uint256 v = Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil); + require(v <= type(uint248).max, "HELP"); + return y0 + (v + (py - 1)) / py; + } + } + + function fInverse(uint256 y, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) + internal + pure + returns (uint256) + { + // components of quadratic equation + int256 B = int256((py * (y - y0) + (px - 1)) / px) - (2 * int256(c) - int256(1e18)) * int256(x0) / 1e18; + uint256 C; + uint256 fourAC; + if (x0 < 1e18) { + C = ((1e18 - c) * x0 * x0 + (1e18 - 1)) / 1e18; // upper bound of 1e28 for x0 means this is safe + fourAC = Math.mulDiv(4 * c, C, 1e18, Math.Rounding.Ceil); + } else { + C = Math.mulDiv((1e18 - c), x0 * x0, 1e36, Math.Rounding.Ceil); // upper bound of 1e28 for x0 means this is safe + fourAC = Math.mulDiv(4 * c, C, 1, Math.Rounding.Ceil); + } + + // solve for the square root + uint256 absB = abs(B); + uint256 squaredB; + uint256 discriminant; + uint256 sqrt; + if (absB > 1e33) { + uint256 scale = computeScale(absB); + squaredB = Math.mulDiv(absB / scale, absB, scale, Math.Rounding.Ceil); + discriminant = squaredB + fourAC / (scale * scale); + sqrt = Math.sqrt(discriminant); + sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; + sqrt = sqrt * scale; + } else { + squaredB = Math.mulDiv(absB, absB, 1, Math.Rounding.Ceil); + discriminant = squaredB + fourAC; // keep in 1e36 scale for increased precision ahead of sqrt + sqrt = Math.sqrt(discriminant); // drop back to 1e18 scale + sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; + } + + uint256 x; + if (B <= 0) { + x = Math.mulDiv(absB + sqrt, 1e18, 2 * c, Math.Rounding.Ceil) + 3; + } else { + x = Math.mulDiv(2 * C, 1e18, absB + sqrt, Math.Rounding.Ceil) + 3; + } + + if (x >= x0) { + return x0; + } else { + return x; + } + } + + function computeScale(uint256 x) internal pure returns (uint256 scale) { + uint256 bits = 0; + uint256 tmp = x; + + while (tmp > 0) { + tmp >>= 1; + bits++; + } + + // absB * absB must be <= 2^256 ⇒ bits(B) ≤ 128 + if (bits > 128) { + uint256 excessBits = bits - 128; + // 2^excessBits is how much we need to scale down to prevent overflow + scale = 1 << excessBits; + } else { + scale = 1; + } + } + + function abs(int256 x) internal pure returns (uint256) { + return uint256(x >= 0 ? x : -x); + } } From f38db55d453f456dc4d4ef95446b2ea381fe02ac Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 7 Apr 2025 09:17:27 -0400 Subject: [PATCH 256/312] fix tests, handle error condition --- src/EulerSwap.sol | 2 +- src/EulerSwapPeriphery.sol | 10 +++++----- test/AltDecimals.t.sol | 4 ++-- test/EulerSwapTest.t.sol | 2 +- test/EulerSwapTestBase.t.sol | 2 ++ test/Fees.t.sol | 4 ++-- test/PreserveNav.t.sol | 4 ++-- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 567f445..af74129 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -292,7 +292,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { } /// @dev EulerSwap curve definition - /// Pre-conditions: x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 + /// Pre-conditions: 0 < x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 function f(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { unchecked { uint256 v = Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil); diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index 3c3bf90..864e293 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -15,6 +15,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { error SwapLimitExceeded(); error AmountOutLessThanMin(); error AmountInMoreThanMax(); + error Overflow(); /// @inheritdoc IEulerSwapPeriphery function swapExactIn(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin) @@ -230,9 +231,6 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { ////////////////////////////// - - // Exact version starts here. - // Strategy is to re-calculate everything using f() and fInverse() and see where things break. function search( IEulerSwap eulerSwap, uint112 reserve0, @@ -280,6 +278,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { // exact out if (asset0IsInput) { // swap Y out and X in + require(reserve1 > amount, SwapLimitExceeded()); yNew = reserve1 - amount; if (yNew < y0) { // remain on g() @@ -291,6 +290,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { output = xNew > reserve0 ? xNew - reserve0 : 0; } else { // swap X out and Y in + require(reserve0 > amount, SwapLimitExceeded()); xNew = reserve0 - amount; if (xNew < x0) { // remain on f() @@ -305,11 +305,11 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { } /// @dev EulerSwap curve definition - /// Pre-conditions: x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 + /// Pre-conditions: 0 < x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 function f(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { unchecked { uint256 v = Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil); - require(v <= type(uint248).max, "HELP"); + require(v <= type(uint248).max, Overflow()); return y0 + (v + (py - 1)) / py; } } diff --git a/test/AltDecimals.t.sol b/test/AltDecimals.t.sol index d8eff6c..ea9ed8a 100644 --- a/test/AltDecimals.t.sol +++ b/test/AltDecimals.t.sol @@ -22,7 +22,7 @@ contract AltDecimals is EulerSwapTestBase { assetTST.transfer(address(eulerSwap), amount); { - uint256 qPlus = q + 1; + uint256 qPlus = q + MAX_QUOTE_ERROR + 1; vm.expectRevert(); eulerSwap.swap(0, qPlus, address(this), ""); } @@ -62,7 +62,7 @@ contract AltDecimals is EulerSwapTestBase { assetTST.transfer(address(eulerSwap), amount); { - uint256 qPlus = q + 1; + uint256 qPlus = q + MAX_QUOTE_ERROR + 1; vm.expectRevert(); eulerSwap.swap(0, qPlus, address(this), ""); } diff --git a/test/EulerSwapTest.t.sol b/test/EulerSwapTest.t.sol index c23917d..989fb4b 100644 --- a/test/EulerSwapTest.t.sol +++ b/test/EulerSwapTest.t.sol @@ -159,7 +159,7 @@ contract EulerSwapTest is EulerSwapTestBase { t1.transfer(address(eulerSwap), amount); { - uint256 qPlus = q + 1; + uint256 qPlus = q + MAX_QUOTE_ERROR + 1; vm.expectRevert(); if (dir) eulerSwap.swap(0, qPlus, address(this), ""); else eulerSwap.swap(qPlus, 0, address(this), ""); diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index f67a01d..ca52a2b 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -12,6 +12,8 @@ import {HookMiner} from "v4-periphery/src/utils/HookMiner.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; contract EulerSwapTestBase is EVaultTestBase { + uint256 public constant MAX_QUOTE_ERROR = 4; + address public depositor = makeAddr("depositor"); address public creator = makeAddr("creator"); address public holder = makeAddr("holder"); diff --git a/test/Fees.t.sol b/test/Fees.t.sol index 34c91ce..6bd6abc 100644 --- a/test/Fees.t.sol +++ b/test/Fees.t.sol @@ -41,7 +41,7 @@ contract FeesTest is EulerSwapTestBase { // Pulling out one extra reverts... vm.expectRevert(EulerSwap.CurveViolation.selector); - eulerSwap.swap(0, amountOut + 1, address(this), ""); + eulerSwap.swap(0, amountOut + MAX_QUOTE_ERROR + 1, address(this), ""); // Just right: @@ -92,7 +92,7 @@ contract FeesTest is EulerSwapTestBase { // Pulling out one extra reverts... vm.expectRevert(EulerSwap.CurveViolation.selector); - eulerSwap.swap(0, amountOut + 1, address(this), ""); + eulerSwap.swap(0, amountOut + MAX_QUOTE_ERROR + 1, address(this), ""); // Just right: diff --git a/test/PreserveNav.t.sol b/test/PreserveNav.t.sol index e4fab33..1043804 100644 --- a/test/PreserveNav.t.sol +++ b/test/PreserveNav.t.sol @@ -47,7 +47,7 @@ contract PreserveNav is EulerSwapTestBase { t1.transfer(address(eulerSwap), amount1); { - uint256 qPlus = q + 1; + uint256 qPlus = q + MAX_QUOTE_ERROR + 1; vm.expectRevert(); if (dir1) eulerSwap.swap(0, qPlus, address(this), ""); else eulerSwap.swap(qPlus, 0, address(this), ""); @@ -71,7 +71,7 @@ contract PreserveNav is EulerSwapTestBase { t1.transfer(address(eulerSwap), amount2); { - uint256 qPlus = q + 1; + uint256 qPlus = q + MAX_QUOTE_ERROR + 1; vm.expectRevert(); if (dir2) eulerSwap.swap(0, qPlus, address(this), ""); else eulerSwap.swap(qPlus, 0, address(this), ""); From 36732d1cf74636cdf07a7f8f5d5cdfb5bbc45cb8 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 7 Apr 2025 10:52:49 -0400 Subject: [PATCH 257/312] mega refactor --- TODO | 24 +- {script => script.old}/DeployPool.s.sol | 0 {script => script.old}/DeployProtocol.s.sol | 0 {script => script.old}/README.md | 0 {script => script.old}/ScriptUtil.s.sol | 0 {script => script.old}/SwapExactIn.s.sol | 8 +- .../json/DeployPool_input.json | 0 .../json/DeployProtocol_input.json | 0 .../json/SwapExactIn_input.json | 0 src/CtxLib.sol | 40 ++ src/CurveLib.sol | 114 ++++++ src/EulerSwap.sol | 341 ++++++---------- src/EulerSwapFactory.sol | 80 ++-- src/EulerSwapHook.sol | 235 ----------- src/EulerSwapPeriphery.sol | 376 ++---------------- src/FundsLib.sol | 115 ++++++ src/MetaProxyDeployer.sol | 42 ++ src/QuoteLib.sol | 220 ++++++++++ src/UniswapHook.sol | 123 ++++++ src/interfaces/IEulerSwap.sol | 80 ++-- src/interfaces/IEulerSwapFactory.sol | 17 +- src/interfaces/IEulerSwapPeriphery.sol | 28 +- test/{EulerSwapTest.t.sol => Basic.t.sol} | 2 +- test/Ctx.t.sol | 20 + test/DepositFailures.t.sol | 3 +- test/EulerSwapTestBase.t.sol | 113 ++++-- ...wapFactoryTest.t.sol => FactoryTest.t.sol} | 148 +++---- test/Fees.t.sol | 5 +- ...ulerSwapHook.fees.t.sol => HookFees.t.sol} | 15 +- ...erSwapHook.swaps.t.sol => HookSwaps.t.sol} | 11 +- test/Limits.t.sol | 11 +- ...lerSwapPeriphery.t.sol => Periphery.t.sol} | 69 +++- test/harness/EulerSwapHarness.sol | 19 - {src => test}/utils/HookMiner.sol | 33 +- 34 files changed, 1166 insertions(+), 1126 deletions(-) rename {script => script.old}/DeployPool.s.sol (100%) rename {script => script.old}/DeployProtocol.s.sol (100%) rename {script => script.old}/README.md (100%) rename {script => script.old}/ScriptUtil.s.sol (100%) rename {script => script.old}/SwapExactIn.s.sol (90%) rename {script => script.old}/json/DeployPool_input.json (100%) rename {script => script.old}/json/DeployProtocol_input.json (100%) rename {script => script.old}/json/SwapExactIn_input.json (100%) create mode 100644 src/CtxLib.sol create mode 100644 src/CurveLib.sol delete mode 100644 src/EulerSwapHook.sol create mode 100644 src/FundsLib.sol create mode 100644 src/MetaProxyDeployer.sol create mode 100644 src/QuoteLib.sol create mode 100644 src/UniswapHook.sol rename test/{EulerSwapTest.t.sol => Basic.t.sol} (99%) create mode 100644 test/Ctx.t.sol rename test/{EulerSwapFactoryTest.t.sol => FactoryTest.t.sol} (52%) rename test/{EulerSwapHook.fees.t.sol => HookFees.t.sol} (93%) rename test/{EulerSwapHook.swaps.t.sol => HookSwaps.t.sol} (95%) rename test/{EulerSwapPeriphery.t.sol => Periphery.t.sol} (51%) delete mode 100644 test/harness/EulerSwapHarness.sol rename {src => test}/utils/HookMiner.sol (58%) diff --git a/TODO b/TODO index 6f49436..c243361 100644 --- a/TODO +++ b/TODO @@ -1,27 +1,23 @@ -* Better revert messages when a swap fails due to debt-limit/vault utilisation/etc - * currently they are errors thrown by the vaults or arithmetic underflows - +* docs + ! new flow for activate + ! document that periphery depends on non-malicious eulerSwap instances + ! limitations of getLimits +* update deploy scripts +* TODOs in UniswapHook.sol +* small cleanups in CurveLib +? tighten up getLimits bounds TESTING * when exchange rate in vaults != 1 - - -MISC - -? A really small swap could fail because deposit() results in 0 shares, which causes EVK to revert. Call convertToShares() first? Seems like overkill... -* Improve the efficiency of on-chain quoting - * Probably necessary for supporting non-zero slippage swaps - * Use fInverse() Closed-form quoting solutions - * "Range hints" for the binary search - +* better coverage of swaps done via hooks IDEAS * Currently we have only been supporting stable-stable pairs * What extra considerations would there be for floating pairs? * Automatically re-invest fees? There are a few options: - * Don't do anything: Re-deploing probably isn't a huge deal + * Don't do anything: Re-deploying probably isn't a huge deal * Increase the reserves by the fee amount * Increase the reserves by the extra amount of possible leverage supported by the new fee * Apply fees to a super-concentrated middle section of the curve (needs R&D) diff --git a/script/DeployPool.s.sol b/script.old/DeployPool.s.sol similarity index 100% rename from script/DeployPool.s.sol rename to script.old/DeployPool.s.sol diff --git a/script/DeployProtocol.s.sol b/script.old/DeployProtocol.s.sol similarity index 100% rename from script/DeployProtocol.s.sol rename to script.old/DeployProtocol.s.sol diff --git a/script/README.md b/script.old/README.md similarity index 100% rename from script/README.md rename to script.old/README.md diff --git a/script/ScriptUtil.s.sol b/script.old/ScriptUtil.s.sol similarity index 100% rename from script/ScriptUtil.s.sol rename to script.old/ScriptUtil.s.sol diff --git a/script/SwapExactIn.s.sol b/script.old/SwapExactIn.s.sol similarity index 90% rename from script/SwapExactIn.s.sol rename to script.old/SwapExactIn.s.sol index 87de3c2..bfc51e7 100644 --- a/script/SwapExactIn.s.sol +++ b/script.old/SwapExactIn.s.sol @@ -1,10 +1,14 @@ // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; -import {ScriptUtil} from "./ScriptUtil.s.sol"; -import {IERC20, SafeERC20, EulerSwap} from "../src/EulerSwap.sol"; +import {SafeERC20, IERC20} from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol"; + +import {EulerSwap} from "../src/EulerSwap.sol"; import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; +import {ScriptUtil} from "./ScriptUtil.s.sol"; + + contract SwapExactIn is ScriptUtil { using SafeERC20 for IERC20; diff --git a/script/json/DeployPool_input.json b/script.old/json/DeployPool_input.json similarity index 100% rename from script/json/DeployPool_input.json rename to script.old/json/DeployPool_input.json diff --git a/script/json/DeployProtocol_input.json b/script.old/json/DeployProtocol_input.json similarity index 100% rename from script/json/DeployProtocol_input.json rename to script.old/json/DeployProtocol_input.json diff --git a/script/json/SwapExactIn_input.json b/script.old/json/SwapExactIn_input.json similarity index 100% rename from script/json/SwapExactIn_input.json rename to script.old/json/SwapExactIn_input.json diff --git a/src/CtxLib.sol b/src/CtxLib.sol new file mode 100644 index 0000000..6486461 --- /dev/null +++ b/src/CtxLib.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.27; + +import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; + +library CtxLib { + struct Storage { + uint112 reserve0; + uint112 reserve1; + uint32 status; // 0 = unactivated, 1 = unlocked, 2 = locked + } + + // keccak256("eulerSwap.storage") + bytes32 internal constant CtxStorageLocation = 0xae890085f98619e96ae34ba28d74baa4a4f79785b58fd4afcd3dc0338b79df91; + + function getStorage() internal pure returns (Storage storage s) { + assembly { + s.slot := CtxStorageLocation + } + } + + /// @dev Unpacks encoded Params from trailing calldata. Loosely based on + /// the implementation from EIP-3448 (except length is hard-coded). + function getParams() internal pure returns (IEulerSwap.Params memory p) { + bytes memory data; + + assembly { + let size := 384 + let dataPtr := sub(calldatasize(), size) + data := mload(64) + // increment free memory pointer by metadata size + 32 bytes (length) + mstore(64, add(data, add(size, 32))) + mstore(data, size) + let memPtr := add(data, 32) + calldatacopy(memPtr, dataPtr, size) + } + + return abi.decode(data, (IEulerSwap.Params)); + } +} diff --git a/src/CurveLib.sol b/src/CurveLib.sol new file mode 100644 index 0000000..d3c1062 --- /dev/null +++ b/src/CurveLib.sol @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.27; + +import {Math} from "openzeppelin-contracts/utils/math/Math.sol"; + +import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; + +library CurveLib { + error Overflow(); + error CurveViolation(); + + /// @notice Returns true iff the specified reserve amounts would be acceptable. + /// Acceptable points are on, or above and to-the-right of the swapping curve. + function verify(IEulerSwap.Params memory p, uint256 newReserve0, uint256 newReserve1) + internal + pure + returns (bool) + { + if (newReserve0 > type(uint112).max || newReserve1 > type(uint112).max) return false; + + if (newReserve0 >= p.equilibriumReserve0) { + if (newReserve1 >= p.equilibriumReserve1) return true; + return newReserve0 + >= f(newReserve1, p.priceY, p.priceX, p.equilibriumReserve1, p.equilibriumReserve0, p.concentrationY); + } else { + if (newReserve1 < p.equilibriumReserve1) return false; + return newReserve1 + >= f(newReserve0, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX); + } + } + + /// @dev EulerSwap curve definition + /// Pre-conditions: 0 < x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 + function f(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { + unchecked { + uint256 v = Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil); + require(v <= type(uint248).max, Overflow()); + return y0 + (v + (py - 1)) / py; + } + } + + function fInverse(uint256 y, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) + internal + pure + returns (uint256) + { + // components of quadratic equation + int256 B = int256((py * (y - y0) + (px - 1)) / px) - (2 * int256(c) - int256(1e18)) * int256(x0) / 1e18; + uint256 C; + uint256 fourAC; + if (x0 < 1e18) { + C = ((1e18 - c) * x0 * x0 + (1e18 - 1)) / 1e18; // upper bound of 1e28 for x0 means this is safe + fourAC = Math.mulDiv(4 * c, C, 1e18, Math.Rounding.Ceil); + } else { + C = Math.mulDiv((1e18 - c), x0 * x0, 1e36, Math.Rounding.Ceil); // upper bound of 1e28 for x0 means this is safe + fourAC = Math.mulDiv(4 * c, C, 1, Math.Rounding.Ceil); + } + + // solve for the square root + uint256 absB = abs(B); + uint256 squaredB; + uint256 discriminant; + uint256 sqrt; + if (absB > 1e33) { + uint256 scale = computeScale(absB); + squaredB = Math.mulDiv(absB / scale, absB, scale, Math.Rounding.Ceil); + discriminant = squaredB + fourAC / (scale * scale); + sqrt = Math.sqrt(discriminant); + sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; + sqrt = sqrt * scale; + } else { + squaredB = Math.mulDiv(absB, absB, 1, Math.Rounding.Ceil); + discriminant = squaredB + fourAC; // keep in 1e36 scale for increased precision ahead of sqrt + sqrt = Math.sqrt(discriminant); // drop back to 1e18 scale + sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; + } + + uint256 x; + if (B <= 0) { + x = Math.mulDiv(absB + sqrt, 1e18, 2 * c, Math.Rounding.Ceil) + 3; + } else { + x = Math.mulDiv(2 * C, 1e18, absB + sqrt, Math.Rounding.Ceil) + 3; + } + + if (x >= x0) { + return x0; + } else { + return x; + } + } + + function computeScale(uint256 x) internal pure returns (uint256 scale) { + uint256 bits = 0; + uint256 tmp = x; + + while (tmp > 0) { + tmp >>= 1; + bits++; + } + + // absB * absB must be <= 2^256 ⇒ bits(B) ≤ 128 + if (bits > 128) { + uint256 excessBits = bits - 128; + // 2^excessBits is how much we need to scale down to prevent overflow + scale = 1 << excessBits; + } else { + scale = 1; + } + } + + function abs(int256 x) internal pure returns (uint256) { + return uint256(x >= 0 ? x : -x); + } +} diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index af74129..705dd41 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -1,42 +1,23 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; -import {SafeERC20, IERC20} from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol"; -import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; -import {IEVault, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; -import {Errors as EVKErrors} from "evk/EVault/shared/Errors.sol"; import {IUniswapV2Callee} from "./interfaces/IUniswapV2Callee.sol"; -import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; -import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; + import {EVCUtil} from "evc/utils/EVCUtil.sol"; -import {Math} from "openzeppelin-contracts/utils/math/Math.sol"; +import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; -contract EulerSwap is IEulerSwap, EVCUtil { - using SafeERC20 for IERC20; +import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; +import {UniswapHook} from "./UniswapHook.sol"; +import {CtxLib} from "./CtxLib.sol"; +import {FundsLib} from "./FundsLib.sol"; +import {CurveLib} from "./CurveLib.sol"; +import {QuoteLib} from "./QuoteLib.sol"; +contract EulerSwap is IEulerSwap, EVCUtil, UniswapHook { bytes32 public constant curve = bytes32("EulerSwap v1"); - address public immutable vault0; - address public immutable vault1; - address public immutable asset0; - address public immutable asset1; - address public immutable eulerAccount; - uint112 public immutable equilibriumReserve0; - uint112 public immutable equilibriumReserve1; - uint256 public immutable fee; - uint256 public immutable protocolFee; - address public immutable protocolFeeRecipient; - - uint256 public immutable priceX; - uint256 public immutable priceY; - uint256 public immutable concentrationX; - uint256 public immutable concentrationY; - - uint112 public reserve0; - uint112 public reserve1; - uint32 public status; // 0 = unactivated, 1 = unlocked, 2 = locked - - event EulerSwapCreated(address indexed asset0, address indexed asset1); + event EulerSwapActivated(address indexed asset0, address indexed asset1); event Swap( address indexed sender, uint256 amount0In, @@ -49,255 +30,155 @@ contract EulerSwap is IEulerSwap, EVCUtil { ); error Locked(); - error Overflow(); + error AlreadyActivated(); error BadParam(); error AmountTooBig(); error AssetsOutOfOrderOrEqual(); - error CurveViolation(); - error DepositFailure(bytes reason); + + constructor(address evc_, address poolManager_) EVCUtil(evc_) UniswapHook(evc_, poolManager_) { + CtxLib.Storage storage s = CtxLib.getStorage(); + + s.status = 2; // can only be used via delegatecall proxy + } modifier nonReentrant() { - if (status == 0) activate(); - require(status == 1, Locked()); - status = 2; + CtxLib.Storage storage s = CtxLib.getStorage(); + + require(s.status == 1, Locked()); + s.status = 2; _; - status = 1; + s.status = 1; } - constructor(Params memory params, CurveParams memory curveParams) EVCUtil(IEVault(params.vault0).EVC()) { - // EulerSwap params - - require(params.fee < 1e18, BadParam()); - require(curveParams.priceX > 0 && curveParams.priceY > 0, BadParam()); - require(curveParams.priceX <= 1e36 && curveParams.priceY <= 1e36, BadParam()); - require(curveParams.concentrationX <= 1e18 && curveParams.concentrationY <= 1e18, BadParam()); - - address asset0Addr = IEVault(params.vault0).asset(); - address asset1Addr = IEVault(params.vault1).asset(); - require(asset0Addr < asset1Addr, AssetsOutOfOrderOrEqual()); - - vault0 = params.vault0; - vault1 = params.vault1; - asset0 = asset0Addr; - asset1 = asset1Addr; - eulerAccount = params.eulerAccount; - equilibriumReserve0 = params.equilibriumReserve0; - equilibriumReserve1 = params.equilibriumReserve1; - reserve0 = params.currReserve0; - reserve1 = params.currReserve1; - fee = params.fee; - protocolFee = 0.1e18; - protocolFeeRecipient = address(0); - - // Curve params - - priceX = curveParams.priceX; - priceY = curveParams.priceY; - concentrationX = curveParams.concentrationX; - concentrationY = curveParams.concentrationY; - - // Validate reserves - - require(verify(reserve0, reserve1), CurveViolation()); - require(!verify(reserve0 > 0 ? reserve0 - 1 : 0, reserve1), CurveViolation()); - require(!verify(reserve0, reserve1 > 0 ? reserve1 - 1 : 0), CurveViolation()); - - emit EulerSwapCreated(asset0Addr, asset1Addr); + modifier nonReentrantView() { + CtxLib.Storage storage s = CtxLib.getStorage(); + require(s.status != 2, Locked()); + + _; } /// @inheritdoc IEulerSwap - function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) - external - callThroughEVC - nonReentrant - { - require(amount0Out <= type(uint112).max && amount1Out <= type(uint112).max, AmountTooBig()); + function activate(InitialState calldata initialState) public { + CtxLib.Storage storage s = CtxLib.getStorage(); + Params memory p = CtxLib.getParams(); - // Optimistically send tokens + require(s.status == 0, AlreadyActivated()); + s.status = 1; - if (amount0Out > 0) withdrawAssets(vault0, amount0Out, to); - if (amount1Out > 0) withdrawAssets(vault1, amount1Out, to); + // Parameter validation - // Invoke callback + require(p.fee < 1e18, BadParam()); + require(p.priceX > 0 && p.priceY > 0, BadParam()); + require(p.priceX <= 1e36 && p.priceY <= 1e36, BadParam()); + require(p.concentrationX <= 1e18 && p.concentrationY <= 1e18, BadParam()); - if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(_msgSender(), amount0Out, amount1Out, data); + { + address asset0Addr = IEVault(p.vault0).asset(); + address asset1Addr = IEVault(p.vault1).asset(); + require(asset0Addr < asset1Addr, AssetsOutOfOrderOrEqual()); + emit EulerSwapActivated(asset0Addr, asset1Addr); + } - // Deposit all available funds, adjust received amounts downward to collect fees + // Initial state - uint256 amount0In = depositAssets(asset0, vault0); - uint256 amount1In = depositAssets(asset1, vault1); + s.reserve0 = initialState.currReserve0; + s.reserve1 = initialState.currReserve1; - // Verify curve invariant is satisfied + require(CurveLib.verify(p, s.reserve0, s.reserve1), CurveLib.CurveViolation()); + require(!CurveLib.verify(p, s.reserve0 > 0 ? s.reserve0 - 1 : 0, s.reserve1), CurveLib.CurveViolation()); + require(!CurveLib.verify(p, s.reserve0, s.reserve1 > 0 ? s.reserve1 - 1 : 0), CurveLib.CurveViolation()); - { - uint256 newReserve0 = reserve0 + amount0In - amount0Out; - uint256 newReserve1 = reserve1 + amount1In - amount1Out; - - require(verify(newReserve0, newReserve1), CurveViolation()); - - reserve0 = uint112(newReserve0); - reserve1 = uint112(newReserve1); - - emit Swap( - _msgSender(), - amount0In, - amount1In, - amount0Out, - amount1Out, - uint112(newReserve0), - uint112(newReserve1), - to - ); - } - } + // Configure external contracts - /// @inheritdoc IEulerSwap - function getReserves() external view returns (uint112, uint112, uint32) { - require(status != 2, Locked()); - return (reserve0, reserve1, status); + FundsLib.approveVault(p.vault0); + FundsLib.approveVault(p.vault1); + + IEVC(evc).enableCollateral(p.eulerAccount, p.vault0); + IEVC(evc).enableCollateral(p.eulerAccount, p.vault1); + + // Uniswap hooks + + if (address(poolManager) != address(0)) activateHook(p); } /// @inheritdoc IEulerSwap - function EVC() external view override(EVCUtil, IEulerSwap) returns (address) { - return address(evc); + function getParams() external pure returns (Params memory) { + return CtxLib.getParams(); } /// @inheritdoc IEulerSwap - function activate() public { - require(status != 2, Locked()); - status = 1; - - approveVault(asset0, vault0); - approveVault(asset1, vault1); + function getAssets() external view returns (address asset0, address asset1) { + Params memory p = CtxLib.getParams(); - IEVC(evc).enableCollateral(eulerAccount, vault0); - IEVC(evc).enableCollateral(eulerAccount, vault1); + asset0 = IEVault(p.vault0).asset(); + asset1 = IEVault(p.vault1).asset(); } /// @inheritdoc IEulerSwap - function verify(uint256 newReserve0, uint256 newReserve1) public view returns (bool) { - if (newReserve0 > type(uint112).max || newReserve1 > type(uint112).max) return false; - - if (newReserve0 >= equilibriumReserve0) { - if (newReserve1 >= equilibriumReserve1) return true; - return - newReserve0 >= f(newReserve1, priceY, priceX, equilibriumReserve1, equilibriumReserve0, concentrationY); - } else { - if (newReserve1 < equilibriumReserve1) return false; - return - newReserve1 >= f(newReserve0, priceX, priceY, equilibriumReserve0, equilibriumReserve1, concentrationX); - } + function getReserves() external view nonReentrantView returns (uint112, uint112, uint32) { + CtxLib.Storage storage s = CtxLib.getStorage(); + + return (s.reserve0, s.reserve1, s.status); } - /// @notice Withdraws assets from a vault, first using available balance and then borrowing if needed - /// @param vault The address of the vault to withdraw from - /// @param amount The total amount of assets to withdraw - /// @param to The address that will receive the withdrawn assets - /// @dev This function first checks if there's an existing balance in the vault. - /// @dev If there is, it withdraws the minimum of the requested amount and available balance. - /// @dev If more assets are needed after withdrawal, it enables the controller and borrows the remaining amount. - function withdrawAssets(address vault, uint256 amount, address to) internal { - uint256 balance = myBalance(vault); - - if (balance > 0) { - uint256 avail = amount < balance ? amount : balance; - IEVC(evc).call(vault, eulerAccount, 0, abi.encodeCall(IERC4626.withdraw, (avail, to, eulerAccount))); - amount -= avail; - } + /// @inheritdoc IEulerSwap + function computeQuote(address tokenIn, address tokenOut, uint256 amount, bool exactIn) + external + view + nonReentrantView + returns (uint256) + { + Params memory p = CtxLib.getParams(); - if (amount > 0) { - IEVC(evc).enableController(eulerAccount, vault); - IEVC(evc).call(vault, eulerAccount, 0, abi.encodeCall(IBorrowing.borrow, (amount, to))); - } + return QuoteLib.computeQuote(address(evc), p, QuoteLib.checkTokens(p, tokenIn, tokenOut), amount, exactIn); } - /// @notice Deposits assets into a vault and automatically repays any outstanding debt - /// @param asset The address of the underlying asset - /// @param vault The address of the vault to deposit into - /// @return The amount of assets successfully deposited - /// @dev This function attempts to deposit assets into the specified vault. - /// @dev If the deposit fails with E_ZeroShares error, it safely returns 0 (this happens with very small amounts). - /// @dev After successful deposit, if the user has any outstanding controller-enabled debt, it attempts to repay it. - /// @dev If all debt is repaid, the controller is automatically disabled to reduce gas costs in future operations. - function depositAssets(address asset, address vault) internal returns (uint256) { - uint256 amount = IERC20(asset).balanceOf(address(this)); - if (amount == 0) return 0; + /// @inheritdoc IEulerSwap + function getLimits(address tokenIn, address tokenOut) external view nonReentrantView returns (uint256, uint256) { + Params memory p = CtxLib.getParams(); - uint256 feeAmount = amount * fee / 1e18; + if (!evc.isAccountOperatorAuthorized(p.eulerAccount, address(this))) return (0, 0); - { - uint256 protocolFeeAmount = feeAmount * protocolFee / 1e18; + return QuoteLib.calcLimits(p, QuoteLib.checkTokens(p, tokenIn, tokenOut)); + } - if (protocolFeeAmount != 0) { - IERC20(asset).transfer(protocolFeeRecipient, protocolFeeAmount); - amount -= protocolFeeAmount; - feeAmount -= protocolFeeAmount; - } - } + /// @inheritdoc IEulerSwap + function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) + external + callThroughEVC + nonReentrant + { + require(amount0Out <= type(uint112).max && amount1Out <= type(uint112).max, AmountTooBig()); - uint256 deposited; + CtxLib.Storage storage s = CtxLib.getStorage(); + Params memory p = CtxLib.getParams(); - if (IEVC(evc).isControllerEnabled(eulerAccount, vault)) { - uint256 debt = myDebt(vault); - uint256 repaid = IEVault(vault).repay(amount > debt ? debt : amount, eulerAccount); + // Optimistically send tokens - amount -= repaid; - debt -= repaid; - deposited += repaid; + if (amount0Out > 0) FundsLib.withdrawAssets(address(evc), p, p.vault0, amount0Out, to); + if (amount1Out > 0) FundsLib.withdrawAssets(address(evc), p, p.vault1, amount1Out, to); - if (debt == 0) { - IEVC(evc).call(vault, eulerAccount, 0, abi.encodeCall(IRiskManager.disableController, ())); - } - } + // Invoke callback - if (amount > 0) { - try IEVault(vault).deposit(amount, eulerAccount) {} - catch (bytes memory reason) { - require(bytes4(reason) == EVKErrors.E_ZeroShares.selector, DepositFailure(reason)); - amount = 0; - } + if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(_msgSender(), amount0Out, amount1Out, data); - deposited += amount; - } + // Deposit all available funds, adjust received amounts downward to collect fees - return deposited > feeAmount ? deposited - feeAmount : 0; - } + uint256 amount0In = FundsLib.depositAssets(address(evc), p, p.vault0); + uint256 amount1In = FundsLib.depositAssets(address(evc), p, p.vault1); - /// @notice Approves tokens for a given vault, supporting both standard approvals and permit2 - /// @param asset The address of the token to approve - /// @param vault The address of the vault to approve the token for - function approveVault(address asset, address vault) internal { - address permit2 = IEVault(vault).permit2Address(); - if (permit2 == address(0)) { - IERC20(asset).forceApprove(vault, type(uint256).max); - } else { - IERC20(asset).forceApprove(permit2, type(uint256).max); - IAllowanceTransfer(permit2).approve(asset, vault, type(uint160).max, type(uint48).max); - } - } + // Verify curve invariant is satisfied - /// @notice Retrieves the current debt amount for the pool's eulerAccount - /// @param vault The address of the vault to check for debt - /// @return The amount of debt that the Euler account has in the specified vault - function myDebt(address vault) internal view returns (uint256) { - return IEVault(vault).debtOf(eulerAccount); - } + { + uint256 newReserve0 = s.reserve0 + amount0In - amount0Out; + uint256 newReserve1 = s.reserve1 + amount1In - amount1Out; - /// @notice Calculates the asset balance of the pool's eulerAccount - /// @param vault The address of the vault to check for balance - /// @return The amount of assets that the Euler account has deposited in the specified vault - function myBalance(address vault) internal view returns (uint256) { - uint256 shares = IEVault(vault).balanceOf(eulerAccount); - return shares == 0 ? 0 : IEVault(vault).convertToAssets(shares); - } + require(CurveLib.verify(p, newReserve0, newReserve1), CurveLib.CurveViolation()); - /// @dev EulerSwap curve definition - /// Pre-conditions: 0 < x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 - function f(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { - unchecked { - uint256 v = Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil); - require(v <= type(uint248).max, Overflow()); - return y0 + (v + (py - 1)) / py; + s.reserve0 = uint112(newReserve0); + s.reserve1 = uint112(newReserve1); } + + emit Swap(_msgSender(), amount0In, amount1In, amount0Out, amount1Out, s.reserve0, s.reserve1, to); } } diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 1338a04..d6d7c09 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -1,12 +1,13 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; -import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {IEulerSwapFactory, IEulerSwap} from "./interfaces/IEulerSwapFactory.sol"; -import {EulerSwapHook} from "./EulerSwapHook.sol"; import {EVCUtil} from "ethereum-vault-connector/utils/EVCUtil.sol"; import {GenericFactory} from "evk/GenericFactory/GenericFactory.sol"; +import {EulerSwap} from "./EulerSwap.sol"; +import {MetaProxyDeployer} from "./MetaProxyDeployer.sol"; + /// @title EulerSwapFactory contract /// @custom:security-contact security@euler.xyz /// @author Euler Labs (https://www.eulerlabs.com/) @@ -15,27 +16,14 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { address[] private allPools; /// @dev Vaults must be deployed by this factory address public immutable evkFactory; + /// @dev The EulerSwap code instance that will be proxied to + address public immutable eulerSwapImpl; /// @dev Mapping between euler account and EulerAccountState mapping(address eulerAccount => EulerAccountState state) private eulerAccountState; mapping(address asset0 => mapping(address asset1 => address[])) private poolMap; - IPoolManager immutable poolManager; - - event PoolDeployed( - address indexed asset0, - address indexed asset1, - address vault0, - address vault1, - uint256 indexed fee, - address eulerAccount, - uint256 reserve0, - uint256 reserve1, - uint256 priceX, - uint256 priceY, - uint256 concentrationX, - uint256 concentrationY, - address pool - ); + event PoolDeployed(address indexed asset0, address indexed asset1, address indexed eulerAccount, address pool); + event PoolConfig(address indexed pool, IEulerSwap.Params params, IEulerSwap.InitialState initialState); event PoolUninstalled(address indexed asset0, address indexed asset1, address indexed eulerAccount, address pool); error InvalidQuery(); @@ -45,13 +33,13 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { error InvalidVaultImplementation(); error SliceOutOfBounds(); - constructor(IPoolManager _manager, address evc, address evkFactory_) EVCUtil(evc) { - poolManager = _manager; + constructor(address evc, address evkFactory_, address eulerSwapImpl_) EVCUtil(evc) { evkFactory = evkFactory_; + eulerSwapImpl = eulerSwapImpl_; } /// @inheritdoc IEulerSwapFactory - function deployPool(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams, bytes32 salt) + function deployPool(IEulerSwap.Params memory params, IEulerSwap.InitialState memory initialState, bytes32 salt) external returns (address) { @@ -63,28 +51,19 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { uninstall(params.eulerAccount); - EulerSwapHook pool = - new EulerSwapHook{salt: keccak256(abi.encode(params.eulerAccount, salt))}(poolManager, params, curveParams); + EulerSwap pool = EulerSwap( + MetaProxyDeployer.deployMetaProxy( + eulerSwapImpl, abi.encode(params), keccak256(abi.encode(params.eulerAccount, salt)) + ) + ); updateEulerAccountState(params.eulerAccount, address(pool)); - pool.activate(); - - emit PoolDeployed( - pool.asset0(), - pool.asset1(), - params.vault0, - params.vault1, - pool.fee(), - params.eulerAccount, - params.currReserve0, - params.currReserve1, - curveParams.priceX, - curveParams.priceY, - curveParams.concentrationX, - curveParams.concentrationY, - address(pool) - ); + pool.activate(initialState); + + (address asset0, address asset1) = pool.getAssets(); + emit PoolDeployed(asset0, asset1, params.eulerAccount, address(pool)); + emit PoolConfig(address(pool), params, initialState); return address(pool); } @@ -95,11 +74,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { } /// @inheritdoc IEulerSwapFactory - function computePoolAddress( - IEulerSwap.Params memory poolParams, - IEulerSwap.CurveParams memory curveParams, - bytes32 salt - ) external view returns (address) { + function computePoolAddress(IEulerSwap.Params memory poolParams, bytes32 salt) external view returns (address) { return address( uint160( uint256( @@ -108,11 +83,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { bytes1(0xff), address(this), keccak256(abi.encode(address(poolParams.eulerAccount), salt)), - keccak256( - abi.encodePacked( - type(EulerSwapHook).creationCode, abi.encode(poolManager, poolParams, curveParams) - ) - ) + keccak256(MetaProxyDeployer.creationCodeMetaProxy(eulerSwapImpl, abi.encode(poolParams))) ) ) ) @@ -120,11 +91,6 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { ); } - /// @inheritdoc IEulerSwapFactory - function EVC() external view override(EVCUtil, IEulerSwapFactory) returns (address) { - return address(evc); - } - /// @inheritdoc IEulerSwapFactory function poolByEulerAccount(address eulerAccount) external view returns (address) { return eulerAccountState[eulerAccount].pool; @@ -221,7 +187,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { /// @param pool The address of the pool to query /// @return The addresses of asset0 and asset1 in the pool function _getAssets(address pool) internal view returns (address, address) { - return (IEulerSwap(pool).asset0(), IEulerSwap(pool).asset1()); + return IEulerSwap(pool).getAssets(); } /// @notice Returns a slice of an array of addresses diff --git a/src/EulerSwapHook.sol b/src/EulerSwapHook.sol deleted file mode 100644 index d2a019f..0000000 --- a/src/EulerSwapHook.sol +++ /dev/null @@ -1,235 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.27; - -import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {BaseHook} from "v4-periphery/src/utils/BaseHook.sol"; -import {PoolKey} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; -import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; -import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; -import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol"; -import { - BeforeSwapDelta, toBeforeSwapDelta, BeforeSwapDeltaLibrary -} from "@uniswap/v4-core/src/types/BeforeSwapDelta.sol"; -import {EulerSwap, IEulerSwap, IEVault} from "./EulerSwap.sol"; - -contract EulerSwapHook is EulerSwap, BaseHook { - using SafeCast for uint256; - - PoolKey internal _poolKey; - - constructor(IPoolManager _manager, Params memory params, CurveParams memory curveParams) - EulerSwap(params, curveParams) - BaseHook(_manager) - { - address asset0Addr = IEVault(params.vault0).asset(); - address asset1Addr = IEVault(params.vault1).asset(); - - // convert fee in WAD to pips. 0.003e18 / 1e12 = 3000 = 0.30% - uint24 fee = uint24(params.fee / 1e12); - - _poolKey = PoolKey({ - currency0: Currency.wrap(asset0Addr), - currency1: Currency.wrap(asset1Addr), - fee: fee, - tickSpacing: 60, // TODO: fix arbitrary tick spacing - hooks: IHooks(address(this)) - }); - - // create the pool on v4, using starting price as sqrtPrice(1/1) * Q96 - poolManager.initialize(_poolKey, 79228162514264337593543950336); - } - - /// @dev Helper function to return the poolKey as its struct type - function poolKey() external view returns (PoolKey memory) { - return _poolKey; - } - - function _beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata) - internal - override - returns (bytes4, BeforeSwapDelta, uint24) - { - // determine inbound/outbound token based on 0->1 or 1->0 swap - bool zeroForOne = params.zeroForOne; - - uint256 amountInWithoutFee; - uint256 amountOut; - BeforeSwapDelta returnDelta; - - { - (Currency inputCurrency, Currency outputCurrency) = - zeroForOne ? (key.currency0, key.currency1) : (key.currency1, key.currency0); - - uint256 amountIn; - bool isExactInput = params.amountSpecified < 0; - if (isExactInput) { - amountIn = uint256(-params.amountSpecified); - amountOut = computeQuote(zeroForOne, uint256(-params.amountSpecified), true); - } else { - amountIn = computeQuote(zeroForOne, uint256(params.amountSpecified), false); - amountOut = uint256(params.amountSpecified); - } - - // return the delta to the PoolManager, so it can process the accounting - // exact input: - // specifiedDelta = positive, to offset the input token taken by the hook (negative delta) - // unspecifiedDelta = negative, to offset the credit of the output token paid by the hook (positive delta) - // exact output: - // specifiedDelta = negative, to offset the output token paid by the hook (positive delta) - // unspecifiedDelta = positive, to offset the input token taken by the hook (negative delta) - returnDelta = isExactInput - ? toBeforeSwapDelta(amountIn.toInt128(), -(amountOut.toInt128())) - : toBeforeSwapDelta(-(amountOut.toInt128()), amountIn.toInt128()); - - // take the input token, from the PoolManager to the Euler vault - // the debt will be paid by the swapper via the swap router - // TODO: can we optimize the transfer by pulling from PoolManager directly to Euler? - poolManager.take(inputCurrency, address(this), amountIn); - amountInWithoutFee = depositAssets(zeroForOne ? asset0 : asset1, zeroForOne ? vault0 : vault1); - - // pay the output token, to the PoolManager from an Euler vault - // the credit will be forwarded to the swap router, which then forwards it to the swapper - poolManager.sync(outputCurrency); - withdrawAssets(zeroForOne ? vault1 : vault0, amountOut, address(poolManager)); - poolManager.settle(); - } - - { - uint256 newReserve0 = zeroForOne ? (reserve0 + amountInWithoutFee) : (reserve0 - amountOut); - uint256 newReserve1 = !zeroForOne ? (reserve1 + amountInWithoutFee) : (reserve1 - amountOut); - - require(newReserve0 <= type(uint112).max && newReserve1 <= type(uint112).max, Overflow()); - require(verify(newReserve0, newReserve1), CurveViolation()); - - reserve0 = uint112(newReserve0); - reserve1 = uint112(newReserve1); - } - - return (BaseHook.beforeSwap.selector, returnDelta, 0); - } - - // TODO: fix salt mining & verification for the hook - function getHookPermissions() public pure override returns (Hooks.Permissions memory) {} - function validateHookAddress(BaseHook) internal pure override {} - - error SwapLimitExceeded(); - error OperatorNotInstalled(); - - function computeQuote(bool asset0IsInput, uint256 amount, bool exactIn) internal view returns (uint256) { - require(evc.isAccountOperatorAuthorized(eulerAccount, address(this)), OperatorNotInstalled()); - require(amount <= type(uint112).max, SwapLimitExceeded()); - - // exactIn: decrease effective amountIn - if (exactIn) amount = amount - (amount * fee / 1e18); - - (uint256 inLimit, uint256 outLimit) = calcLimits(asset0IsInput); - - uint256 quote = binarySearch(amount, exactIn, asset0IsInput); - - if (exactIn) { - // if `exactIn`, `quote` is the amount of assets to buy from the AMM - require(amount <= inLimit && quote <= outLimit, SwapLimitExceeded()); - } else { - // if `!exactIn`, `amount` is the amount of assets to buy from the AMM - require(amount <= outLimit && quote <= inLimit, SwapLimitExceeded()); - } - - // exactOut: inflate required amountIn - if (!exactIn) quote = (quote * 1e18) / (1e18 - fee); - - return quote; - } - - function binarySearch(uint256 amount, bool exactIn, bool asset0IsInput) internal view returns (uint256 output) { - int256 dx; - int256 dy; - - if (exactIn) { - if (asset0IsInput) dx = int256(amount); - else dy = int256(amount); - } else { - if (asset0IsInput) dy = -int256(amount); - else dx = -int256(amount); - } - - unchecked { - int256 reserve0New = int256(uint256(reserve0)) + dx; - int256 reserve1New = int256(uint256(reserve1)) + dy; - require(reserve0New > 0 && reserve1New > 0, SwapLimitExceeded()); - - uint256 low; - uint256 high = type(uint112).max; - - while (low < high) { - uint256 mid = (low + high) / 2; - require(mid > 0, SwapLimitExceeded()); - (uint256 a, uint256 b) = dy == 0 ? (uint256(reserve0New), mid) : (mid, uint256(reserve1New)); - if (verify(a, b)) { - high = mid; - } else { - low = mid + 1; - } - } - - require(high < type(uint112).max, SwapLimitExceeded()); // at least one point verified - - if (dx != 0) dy = int256(low) - reserve1New; - else dx = int256(low) - reserve0New; - } - - if (exactIn) { - if (asset0IsInput) output = uint256(-dy); - else output = uint256(-dx); - } else { - if (asset0IsInput) output = dx >= 0 ? uint256(dx) : 0; - else output = dy >= 0 ? uint256(dy) : 0; - } - } - - function calcLimits(bool asset0IsInput) internal view returns (uint256, uint256) { - uint256 inLimit = type(uint112).max; - uint256 outLimit = type(uint112).max; - - (IEVault vault0, IEVault vault1) = (IEVault(vault0), IEVault(vault1)); - // Supply caps on input - { - IEVault vault = (asset0IsInput ? vault0 : vault1); - uint256 maxDeposit = vault.debtOf(eulerAccount) + vault.maxDeposit(eulerAccount); - if (maxDeposit < inLimit) inLimit = maxDeposit; - } - - // Remaining reserves of output - { - uint112 reserveLimit = asset0IsInput ? reserve1 : reserve0; - if (reserveLimit < outLimit) outLimit = reserveLimit; - } - - // Remaining cash and borrow caps in output - { - IEVault vault = (asset0IsInput ? vault1 : vault0); - - uint256 cash = vault.cash(); - if (cash < outLimit) outLimit = cash; - - (, uint16 borrowCap) = vault.caps(); - uint256 maxWithdraw = decodeCap(uint256(borrowCap)); - maxWithdraw = vault.totalBorrows() > maxWithdraw ? 0 : maxWithdraw - vault.totalBorrows(); - if (maxWithdraw > cash) maxWithdraw = cash; - maxWithdraw += vault.convertToAssets(vault.balanceOf(eulerAccount)); - if (maxWithdraw < outLimit) outLimit = maxWithdraw; - } - - return (inLimit, outLimit); - } - - function decodeCap(uint256 amountCap) internal pure returns (uint256) { - if (amountCap == 0) return type(uint256).max; - - unchecked { - // Cannot overflow because this is less than 2**256: - // 10**(2**6 - 1) * (2**10 - 1) = 1.023e+66 - return 10 ** (amountCap & 63) * (amountCap >> 6) / 100; - } - } -} diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index 864e293..66d94f3 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -1,42 +1,56 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; +import {SafeERC20, IERC20} from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol"; + import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; import {IEulerSwapPeriphery} from "./interfaces/IEulerSwapPeriphery.sol"; -import {IERC20, IEulerSwap, SafeERC20} from "./EulerSwap.sol"; -import {Math} from "openzeppelin-contracts/utils/math/Math.sol"; +import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; contract EulerSwapPeriphery is IEulerSwapPeriphery { using SafeERC20 for IERC20; - error UnsupportedPair(); - error OperatorNotInstalled(); - error SwapLimitExceeded(); error AmountOutLessThanMin(); error AmountInMoreThanMax(); - error Overflow(); + error DeadlineExpired(); /// @inheritdoc IEulerSwapPeriphery - function swapExactIn(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin) - external - { - uint256 amountOut = computeQuote(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountIn, true); + function swapExactIn( + address eulerSwap, + address tokenIn, + address tokenOut, + uint256 amountIn, + address receiver, + uint256 amountOutMin, + uint256 deadline + ) external { + require(deadline == 0 || deadline >= block.timestamp, DeadlineExpired()); + + uint256 amountOut = IEulerSwap(eulerSwap).computeQuote(tokenIn, tokenOut, amountIn, true); require(amountOut >= amountOutMin, AmountOutLessThanMin()); - swap(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountIn, amountOut); + swap(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountIn, amountOut, receiver); } /// @inheritdoc IEulerSwapPeriphery - function swapExactOut(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut, uint256 amountInMax) - external - { - uint256 amountIn = computeQuote(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountOut, false); + function swapExactOut( + address eulerSwap, + address tokenIn, + address tokenOut, + uint256 amountOut, + address receiver, + uint256 amountInMax, + uint256 deadline + ) external { + require(deadline == 0 || deadline >= block.timestamp, DeadlineExpired()); + + uint256 amountIn = IEulerSwap(eulerSwap).computeQuote(tokenIn, tokenOut, amountOut, false); require(amountIn <= amountInMax, AmountInMoreThanMax()); - swap(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountIn, amountOut); + swap(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountIn, amountOut, receiver); } /// @inheritdoc IEulerSwapPeriphery @@ -45,7 +59,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { view returns (uint256) { - return computeQuote(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountIn, true); + return IEulerSwap(eulerSwap).computeQuote(tokenIn, tokenOut, amountIn, true); } /// @inheritdoc IEulerSwapPeriphery @@ -54,18 +68,12 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { view returns (uint256) { - return computeQuote(IEulerSwap(eulerSwap), tokenIn, tokenOut, amountOut, false); + return IEulerSwap(eulerSwap).computeQuote(tokenIn, tokenOut, amountOut, false); } /// @inheritdoc IEulerSwapPeriphery function getLimits(address eulerSwap, address tokenIn, address tokenOut) external view returns (uint256, uint256) { - if ( - !IEVC(IEulerSwap(eulerSwap).EVC()).isAccountOperatorAuthorized( - IEulerSwap(eulerSwap).eulerAccount(), eulerSwap - ) - ) return (0, 0); - - return calcLimits(IEulerSwap(eulerSwap), checkTokens(IEulerSwap(eulerSwap), tokenIn, tokenOut)); + return IEulerSwap(eulerSwap).getLimits(tokenIn, tokenOut); } /// @dev Internal function to execute a token swap through EulerSwap @@ -74,316 +82,18 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { /// @param tokenOut The address of the output token being received /// @param amountIn The amount of input tokens to swap /// @param amountOut The amount of output tokens to receive - function swap(IEulerSwap eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut) - internal - { + /// @param receiver The address that should receive the swap output + function swap( + IEulerSwap eulerSwap, + address tokenIn, + address tokenOut, + uint256 amountIn, + uint256 amountOut, + address receiver + ) internal { IERC20(tokenIn).safeTransferFrom(msg.sender, address(eulerSwap), amountIn); bool isAsset0In = tokenIn < tokenOut; - (isAsset0In) ? eulerSwap.swap(0, amountOut, msg.sender, "") : eulerSwap.swap(amountOut, 0, msg.sender, ""); - } - - /// @dev Computes the quote for a swap by applying fees and validating state conditions - /// @param eulerSwap The EulerSwap contract to quote from - /// @param tokenIn The input token address - /// @param tokenOut The output token address - /// @param amount The amount to quote (input amount if exactIn=true, output amount if exactIn=false) - /// @param exactIn True if quoting for exact input amount, false if quoting for exact output amount - /// @return The quoted amount (output amount if exactIn=true, input amount if exactIn=false) - /// @dev Validates: - /// - EulerSwap operator is installed - /// - Token pair is supported - /// - Sufficient reserves exist - /// - Sufficient cash is available - function computeQuote(IEulerSwap eulerSwap, address tokenIn, address tokenOut, uint256 amount, bool exactIn) - internal - view - returns (uint256) - { - require( - IEVC(eulerSwap.EVC()).isAccountOperatorAuthorized(eulerSwap.eulerAccount(), address(eulerSwap)), - OperatorNotInstalled() - ); - require(amount <= type(uint112).max, SwapLimitExceeded()); - - uint256 fee = eulerSwap.fee(); - (uint112 reserve0, uint112 reserve1,) = eulerSwap.getReserves(); - - // exactIn: decrease effective amountIn - if (exactIn) amount = amount - (amount * fee / 1e18); - - bool asset0IsInput = checkTokens(eulerSwap, tokenIn, tokenOut); - (uint256 inLimit, uint256 outLimit) = calcLimits(eulerSwap, asset0IsInput); - - uint256 quote = search(eulerSwap, reserve0, reserve1, amount, exactIn, asset0IsInput); - - if (exactIn) { - // if `exactIn`, `quote` is the amount of assets to buy from the AMM - require(amount <= inLimit && quote <= outLimit, SwapLimitExceeded()); - } else { - // if `!exactIn`, `amount` is the amount of assets to buy from the AMM - require(amount <= outLimit && quote <= inLimit, SwapLimitExceeded()); - } - - // exactOut: inflate required amountIn - if (!exactIn) quote = (quote * 1e18) / (1e18 - fee); - - return quote; - } - - /** - * @notice Calculates the maximum input and output amounts for a swap based on protocol constraints - * @dev Determines limits by checking multiple factors: - * 1. Supply caps and existing debt for the input token - * 2. Available reserves in the EulerSwap for the output token - * 3. Available cash and borrow caps for the output token - * 4. Account balances in the respective vaults - * - * @param es The EulerSwap contract to calculate limits for - * @param asset0IsInput Boolean indicating whether asset0 (true) or asset1 (false) is the input token - * @return uint256 Maximum amount of input token that can be deposited - * @return uint256 Maximum amount of output token that can be withdrawn - */ - function calcLimits(IEulerSwap es, bool asset0IsInput) internal view returns (uint256, uint256) { - uint256 inLimit = type(uint112).max; - uint256 outLimit = type(uint112).max; - - address eulerAccount = es.eulerAccount(); - (IEVault vault0, IEVault vault1) = (IEVault(es.vault0()), IEVault(es.vault1())); - // Supply caps on input - { - IEVault vault = (asset0IsInput ? vault0 : vault1); - uint256 maxDeposit = vault.debtOf(eulerAccount) + vault.maxDeposit(eulerAccount); - if (maxDeposit < inLimit) inLimit = maxDeposit; - } - - // Remaining reserves of output - { - (uint112 reserve0, uint112 reserve1,) = es.getReserves(); - uint112 reserveLimit = asset0IsInput ? reserve1 : reserve0; - if (reserveLimit < outLimit) outLimit = reserveLimit; - } - - // Remaining cash and borrow caps in output - { - IEVault vault = (asset0IsInput ? vault1 : vault0); - - uint256 cash = vault.cash(); - if (cash < outLimit) outLimit = cash; - - (, uint16 borrowCap) = vault.caps(); - uint256 maxWithdraw = decodeCap(uint256(borrowCap)); - maxWithdraw = vault.totalBorrows() > maxWithdraw ? 0 : maxWithdraw - vault.totalBorrows(); - if (maxWithdraw > cash) maxWithdraw = cash; - maxWithdraw += vault.convertToAssets(vault.balanceOf(eulerAccount)); - if (maxWithdraw < outLimit) outLimit = maxWithdraw; - } - - return (inLimit, outLimit); - } - - /** - * @notice Decodes a compact-format cap value to its actual numerical value - * @dev The cap uses a compact-format where: - * - If amountCap == 0, there's no cap (returns max uint256) - * - Otherwise, the lower 6 bits represent the exponent (10^exp) - * - The upper bits (>> 6) represent the mantissa - * - The formula is: (10^exponent * mantissa) / 100 - * @param amountCap The compact-format cap value to decode - * @return The actual numerical cap value (type(uint256).max if uncapped) - * @custom:security Uses unchecked math for gas optimization as calculations cannot overflow: - * maximum possible value 10^(2^6-1) * (2^10-1) ≈ 1.023e+66 < 2^256 - */ - function decodeCap(uint256 amountCap) internal pure returns (uint256) { - if (amountCap == 0) return type(uint256).max; - - unchecked { - // Cannot overflow because this is less than 2**256: - // 10**(2**6 - 1) * (2**10 - 1) = 1.023e+66 - return 10 ** (amountCap & 63) * (amountCap >> 6) / 100; - } - } - - /** - * @notice Verifies that the given tokens are supported by the EulerSwap pool and determines swap direction - * @dev Returns a boolean indicating whether the input token is asset0 (true) or asset1 (false) - * @param eulerSwap The EulerSwap pool contract to check against - * @param tokenIn The input token address for the swap - * @param tokenOut The output token address for the swap - * @return asset0IsInput True if tokenIn is asset0 and tokenOut is asset1, false if reversed - * @custom:error UnsupportedPair Thrown if the token pair is not supported by the EulerSwap pool - */ - function checkTokens(IEulerSwap eulerSwap, address tokenIn, address tokenOut) - internal - view - returns (bool asset0IsInput) - { - address asset0 = eulerSwap.asset0(); - address asset1 = eulerSwap.asset1(); - - if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true; - else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; - else revert UnsupportedPair(); - } - - - - - ////////////////////////////// - - function search( - IEulerSwap eulerSwap, - uint112 reserve0, - uint112 reserve1, - uint256 amount, - bool exactIn, - bool asset0IsInput - ) internal view returns (uint256 output) { - uint256 px = eulerSwap.priceX(); - uint256 py = eulerSwap.priceY(); - uint256 x0 = eulerSwap.equilibriumReserve0(); - uint256 y0 = eulerSwap.equilibriumReserve1(); - uint256 cx = eulerSwap.concentrationX(); - uint256 cy = eulerSwap.concentrationY(); - - uint256 xNew; - uint256 yNew; - - if (exactIn) { - // exact in - if (asset0IsInput) { - // swap X in and Y out - xNew = reserve0 + amount; - if (xNew < x0) { - // remain on f() - yNew = f(xNew, px, py, x0, y0, cx); - } else { - // move to g() - yNew = fInverse(xNew, py, px, y0, x0, cy); - } - output = reserve1 > yNew ? reserve1 - yNew : 0; - } else { - // swap Y in and X out - yNew = reserve1 + amount; - if (yNew < y0) { - // remain on g() - xNew = f(yNew, py, px, y0, x0, cy); - } else { - // move to f() - xNew = fInverse(yNew, px, py, x0, y0, cx); - } - output = reserve0 > xNew ? reserve0 - xNew : 0; - } - } else { - // exact out - if (asset0IsInput) { - // swap Y out and X in - require(reserve1 > amount, SwapLimitExceeded()); - yNew = reserve1 - amount; - if (yNew < y0) { - // remain on g() - xNew = f(yNew, py, px, y0, x0, cy); - } else { - // move to f() - xNew = fInverse(yNew, px, py, x0, y0, cx); - } - output = xNew > reserve0 ? xNew - reserve0 : 0; - } else { - // swap X out and Y in - require(reserve0 > amount, SwapLimitExceeded()); - xNew = reserve0 - amount; - if (xNew < x0) { - // remain on f() - yNew = f(xNew, py, px, y0, x0, cx); - } else { - // move to g() - yNew = fInverse(xNew, py, px, y0, x0, cy); - } - output = yNew > reserve1 ? yNew - reserve1 : 0; - } - } - } - - /// @dev EulerSwap curve definition - /// Pre-conditions: 0 < x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 - function f(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { - unchecked { - uint256 v = Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil); - require(v <= type(uint248).max, Overflow()); - return y0 + (v + (py - 1)) / py; - } - } - - function fInverse(uint256 y, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) - internal - pure - returns (uint256) - { - // components of quadratic equation - int256 B = int256((py * (y - y0) + (px - 1)) / px) - (2 * int256(c) - int256(1e18)) * int256(x0) / 1e18; - uint256 C; - uint256 fourAC; - if (x0 < 1e18) { - C = ((1e18 - c) * x0 * x0 + (1e18 - 1)) / 1e18; // upper bound of 1e28 for x0 means this is safe - fourAC = Math.mulDiv(4 * c, C, 1e18, Math.Rounding.Ceil); - } else { - C = Math.mulDiv((1e18 - c), x0 * x0, 1e36, Math.Rounding.Ceil); // upper bound of 1e28 for x0 means this is safe - fourAC = Math.mulDiv(4 * c, C, 1, Math.Rounding.Ceil); - } - - // solve for the square root - uint256 absB = abs(B); - uint256 squaredB; - uint256 discriminant; - uint256 sqrt; - if (absB > 1e33) { - uint256 scale = computeScale(absB); - squaredB = Math.mulDiv(absB / scale, absB, scale, Math.Rounding.Ceil); - discriminant = squaredB + fourAC / (scale * scale); - sqrt = Math.sqrt(discriminant); - sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; - sqrt = sqrt * scale; - } else { - squaredB = Math.mulDiv(absB, absB, 1, Math.Rounding.Ceil); - discriminant = squaredB + fourAC; // keep in 1e36 scale for increased precision ahead of sqrt - sqrt = Math.sqrt(discriminant); // drop back to 1e18 scale - sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; - } - - uint256 x; - if (B <= 0) { - x = Math.mulDiv(absB + sqrt, 1e18, 2 * c, Math.Rounding.Ceil) + 3; - } else { - x = Math.mulDiv(2 * C, 1e18, absB + sqrt, Math.Rounding.Ceil) + 3; - } - - if (x >= x0) { - return x0; - } else { - return x; - } - } - - function computeScale(uint256 x) internal pure returns (uint256 scale) { - uint256 bits = 0; - uint256 tmp = x; - - while (tmp > 0) { - tmp >>= 1; - bits++; - } - - // absB * absB must be <= 2^256 ⇒ bits(B) ≤ 128 - if (bits > 128) { - uint256 excessBits = bits - 128; - // 2^excessBits is how much we need to scale down to prevent overflow - scale = 1 << excessBits; - } else { - scale = 1; - } - } - - function abs(int256 x) internal pure returns (uint256) { - return uint256(x >= 0 ? x : -x); + (isAsset0In) ? eulerSwap.swap(0, amountOut, receiver, "") : eulerSwap.swap(amountOut, 0, receiver, ""); } } diff --git a/src/FundsLib.sol b/src/FundsLib.sol new file mode 100644 index 0000000..297e8d6 --- /dev/null +++ b/src/FundsLib.sol @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.27; + +import {SafeERC20, IERC20} from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol"; +import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; + +import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; +import {IEVault, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; +import {Errors as EVKErrors} from "evk/EVault/shared/Errors.sol"; + +import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; + +library FundsLib { + using SafeERC20 for IERC20; + + error DepositFailure(bytes reason); + + /// @notice Approves tokens for a given vault, supporting both standard approvals and permit2 + /// @param vault The address of the vault to approve the token for + function approveVault(address vault) internal { + address asset = IEVault(vault).asset(); + address permit2 = IEVault(vault).permit2Address(); + if (permit2 == address(0)) { + IERC20(asset).forceApprove(vault, type(uint256).max); + } else { + IERC20(asset).forceApprove(permit2, type(uint256).max); + IAllowanceTransfer(permit2).approve(asset, vault, type(uint160).max, type(uint48).max); + } + } + + /// @notice Withdraws assets from a vault, first using available balance and then borrowing if needed + /// @param evc EVC instance + /// @param p EulerSwap parameters + /// @param vault The address of the vault to withdraw from + /// @param amount The total amount of assets to withdraw + /// @param to The address that will receive the withdrawn assets + /// @dev This function first checks if there's an existing balance in the vault. + /// @dev If there is, it withdraws the minimum of the requested amount and available balance. + /// @dev If more assets are needed after withdrawal, it enables the controller and borrows the remaining amount. + function withdrawAssets(address evc, IEulerSwap.Params memory p, address vault, uint256 amount, address to) + internal + { + uint256 balance; + { + uint256 shares = IEVault(vault).balanceOf(p.eulerAccount); + balance = shares == 0 ? 0 : IEVault(vault).convertToAssets(shares); + } + + if (balance > 0) { + uint256 avail = amount < balance ? amount : balance; + IEVC(evc).call(vault, p.eulerAccount, 0, abi.encodeCall(IERC4626.withdraw, (avail, to, p.eulerAccount))); + amount -= avail; + } + + if (amount > 0) { + IEVC(evc).enableController(p.eulerAccount, vault); + IEVC(evc).call(vault, p.eulerAccount, 0, abi.encodeCall(IBorrowing.borrow, (amount, to))); + } + } + + /// @notice Deposits assets into a vault and automatically repays any outstanding debt + /// @param evc EVC instance + /// @param p EulerSwap parameters + /// @param vault The address of the vault to deposit into + /// @return The amount of assets successfully deposited + /// @dev This function attempts to deposit assets into the specified vault. + /// @dev If the deposit fails with E_ZeroShares error, it safely returns 0 (this happens with very small amounts). + /// @dev After successful deposit, if the user has any outstanding controller-enabled debt, it attempts to repay it. + /// @dev If all debt is repaid, the controller is automatically disabled to reduce gas costs in future operations. + function depositAssets(address evc, IEulerSwap.Params memory p, address vault) internal returns (uint256) { + address asset = IEVault(vault).asset(); + + uint256 amount = IERC20(asset).balanceOf(address(this)); + if (amount == 0) return 0; + + uint256 feeAmount = amount * p.fee / 1e18; + + { + uint256 protocolFeeAmount = feeAmount * p.protocolFee / 1e18; + + if (protocolFeeAmount != 0) { + IERC20(asset).transfer(p.protocolFeeRecipient, protocolFeeAmount); + amount -= protocolFeeAmount; + feeAmount -= protocolFeeAmount; + } + } + + uint256 deposited; + + if (IEVC(evc).isControllerEnabled(p.eulerAccount, vault)) { + uint256 debt = IEVault(vault).debtOf(p.eulerAccount); + uint256 repaid = IEVault(vault).repay(amount > debt ? debt : amount, p.eulerAccount); + + amount -= repaid; + debt -= repaid; + deposited += repaid; + + if (debt == 0) { + IEVC(evc).call(vault, p.eulerAccount, 0, abi.encodeCall(IRiskManager.disableController, ())); + } + } + + if (amount > 0) { + try IEVault(vault).deposit(amount, p.eulerAccount) {} + catch (bytes memory reason) { + require(bytes4(reason) == EVKErrors.E_ZeroShares.selector, DepositFailure(reason)); + amount = 0; + } + + deposited += amount; + } + + return deposited > feeAmount ? deposited - feeAmount : 0; + } +} diff --git a/src/MetaProxyDeployer.sol b/src/MetaProxyDeployer.sol new file mode 100644 index 0000000..e906302 --- /dev/null +++ b/src/MetaProxyDeployer.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +/// @title MetaProxyDeployer +/// @custom:security-contact security@euler.xyz +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Contract for deploying minimal proxies with metadata, based on EIP-3448. +/// @dev The metadata of the proxies does not include the data length as defined by EIP-3448, saving gas at a cost of +/// supporting variable size data. +/// @dev This was adapted from the Euler Vault Kit's implementation to use CREATE2 +library MetaProxyDeployer { + error E_DeploymentFailed(); + + // Meta proxy bytecode from EIP-3488 https://eips.ethereum.org/EIPS/eip-3448 + bytes constant BYTECODE_HEAD = hex"600b380380600b3d393df3363d3d373d3d3d3d60368038038091363936013d73"; + bytes constant BYTECODE_TAIL = hex"5af43d3d93803e603457fd5bf3"; + + /// @dev Computes the creation code + function creationCodeMetaProxy(address targetContract, bytes memory metadata) + internal + pure + returns (bytes memory) + { + return abi.encodePacked(BYTECODE_HEAD, targetContract, BYTECODE_TAIL, metadata); + } + + /// @dev Creates a proxy for `targetContract` with metadata from `metadata`. + /// @return addr A non-zero address if successful. + function deployMetaProxy(address targetContract, bytes memory metadata, bytes32 salt) + internal + returns (address addr) + { + bytes memory code = creationCodeMetaProxy(targetContract, metadata); + + assembly ("memory-safe") { + addr := create2(0, add(code, 32), mload(code), salt) + } + + if (addr == address(0)) revert E_DeploymentFailed(); + } +} diff --git a/src/QuoteLib.sol b/src/QuoteLib.sol new file mode 100644 index 0000000..9213eca --- /dev/null +++ b/src/QuoteLib.sol @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.27; + +import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; +import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; +import {CtxLib} from "./CtxLib.sol"; +import {CurveLib} from "./CurveLib.sol"; + +library QuoteLib { + error UnsupportedPair(); + error OperatorNotInstalled(); + error SwapLimitExceeded(); + + /// @dev Computes the quote for a swap by applying fees and validating state conditions + /// @param evc EVC instance + /// @param p The EulerSwap params + /// @param asset0IsInput Swap direction + /// @param amount The amount to quote (input amount if exactIn=true, output amount if exactIn=false) + /// @param exactIn True if quoting for exact input amount, false if quoting for exact output amount + /// @return The quoted amount (output amount if exactIn=true, input amount if exactIn=false) + /// @dev Validates: + /// - EulerSwap operator is installed + /// - Token pair is supported + /// - Sufficient reserves exist + /// - Sufficient cash is available + function computeQuote(address evc, IEulerSwap.Params memory p, bool asset0IsInput, uint256 amount, bool exactIn) + internal + view + returns (uint256) + { + require(IEVC(evc).isAccountOperatorAuthorized(p.eulerAccount, address(this)), OperatorNotInstalled()); + require(amount <= type(uint112).max, SwapLimitExceeded()); + + uint256 fee = p.fee; + + // exactIn: decrease effective amountIn + if (exactIn) amount = amount - (amount * fee / 1e18); + + (uint256 inLimit, uint256 outLimit) = calcLimits(p, asset0IsInput); + + uint256 quote = findCurvePoint(p, amount, exactIn, asset0IsInput); + + if (exactIn) { + // if `exactIn`, `quote` is the amount of assets to buy from the AMM + require(amount <= inLimit && quote <= outLimit, SwapLimitExceeded()); + } else { + // if `!exactIn`, `amount` is the amount of assets to buy from the AMM + require(amount <= outLimit && quote <= inLimit, SwapLimitExceeded()); + } + + // exactOut: inflate required amountIn + if (!exactIn) quote = (quote * 1e18) / (1e18 - fee); + + return quote; + } + + /// @notice Calculates the maximum input and output amounts for a swap based on protocol constraints + /// @dev Determines limits by checking multiple factors: + /// 1. Supply caps and existing debt for the input token + /// 2. Available reserves in the EulerSwap for the output token + /// 3. Available cash and borrow caps for the output token + /// 4. Account balances in the respective vaults + /// @param p The EulerSwap params + /// @param asset0IsInput Boolean indicating whether asset0 (true) or asset1 (false) is the input token + /// @return uint256 Maximum amount of input token that can be deposited + /// @return uint256 Maximum amount of output token that can be withdrawn + function calcLimits(IEulerSwap.Params memory p, bool asset0IsInput) internal view returns (uint256, uint256) { + CtxLib.Storage storage s = CtxLib.getStorage(); + + uint256 inLimit = type(uint112).max; + uint256 outLimit = type(uint112).max; + + address eulerAccount = p.eulerAccount; + (IEVault vault0, IEVault vault1) = (IEVault(p.vault0), IEVault(p.vault1)); + // Supply caps on input + { + IEVault vault = (asset0IsInput ? vault0 : vault1); + uint256 maxDeposit = vault.debtOf(eulerAccount) + vault.maxDeposit(eulerAccount); + if (maxDeposit < inLimit) inLimit = maxDeposit; + } + + // Remaining reserves of output + { + uint112 reserveLimit = asset0IsInput ? s.reserve1 : s.reserve0; + if (reserveLimit < outLimit) outLimit = reserveLimit; + } + + // Remaining cash and borrow caps in output + { + IEVault vault = (asset0IsInput ? vault1 : vault0); + + uint256 cash = vault.cash(); + if (cash < outLimit) outLimit = cash; + + (, uint16 borrowCap) = vault.caps(); + uint256 maxWithdraw = decodeCap(uint256(borrowCap)); + maxWithdraw = vault.totalBorrows() > maxWithdraw ? 0 : maxWithdraw - vault.totalBorrows(); + if (maxWithdraw > cash) maxWithdraw = cash; + maxWithdraw += vault.convertToAssets(vault.balanceOf(eulerAccount)); + if (maxWithdraw < outLimit) outLimit = maxWithdraw; + } + + return (inLimit, outLimit); + } + + /// @notice Decodes a compact-format cap value to its actual numerical value + /// @dev The cap uses a compact-format where: + /// - If amountCap == 0, there's no cap (returns max uint256) + /// - Otherwise, the lower 6 bits represent the exponent (10^exp) + /// - The upper bits (>> 6) represent the mantissa + /// - The formula is: (10^exponent * mantissa) / 100 + /// @param amountCap The compact-format cap value to decode + /// @return The actual numerical cap value (type(uint256).max if uncapped) + /// @custom:security Uses unchecked math for gas optimization as calculations cannot overflow: + /// maximum possible value 10^(2^6-1) * (2^10-1) ≈ 1.023e+66 < 2^256 + function decodeCap(uint256 amountCap) internal pure returns (uint256) { + if (amountCap == 0) return type(uint256).max; + + unchecked { + // Cannot overflow because this is less than 2**256: + // 10**(2**6 - 1) * (2**10 - 1) = 1.023e+66 + return 10 ** (amountCap & 63) * (amountCap >> 6) / 100; + } + } + + /// @notice Verifies that the given tokens are supported by the EulerSwap pool and determines swap direction + /// @dev Returns a boolean indicating whether the input token is asset0 (true) or asset1 (false) + /// @param p The EulerSwap params + /// @param tokenIn The input token address for the swap + /// @param tokenOut The output token address for the swap + /// @return asset0IsInput True if tokenIn is asset0 and tokenOut is asset1, false if reversed + /// @custom:error UnsupportedPair Thrown if the token pair is not supported by the EulerSwap pool + function checkTokens(IEulerSwap.Params memory p, address tokenIn, address tokenOut) + internal + view + returns (bool asset0IsInput) + { + address asset0 = IEVault(p.vault0).asset(); + address asset1 = IEVault(p.vault1).asset(); + + if (tokenIn == asset0 && tokenOut == asset1) asset0IsInput = true; + else if (tokenIn == asset1 && tokenOut == asset0) asset0IsInput = false; + else revert UnsupportedPair(); + } + + function findCurvePoint(IEulerSwap.Params memory p, uint256 amount, bool exactIn, bool asset0IsInput) + internal + view + returns (uint256 output) + { + CtxLib.Storage storage s = CtxLib.getStorage(); + + uint256 px = p.priceX; + uint256 py = p.priceY; + uint256 x0 = p.equilibriumReserve0; + uint256 y0 = p.equilibriumReserve1; + uint256 cx = p.concentrationX; + uint256 cy = p.concentrationY; + uint112 reserve0 = s.reserve0; + uint112 reserve1 = s.reserve1; + + uint256 xNew; + uint256 yNew; + + if (exactIn) { + // exact in + if (asset0IsInput) { + // swap X in and Y out + xNew = reserve0 + amount; + if (xNew < x0) { + // remain on f() + yNew = CurveLib.f(xNew, px, py, x0, y0, cx); + } else { + // move to g() + yNew = CurveLib.fInverse(xNew, py, px, y0, x0, cy); + } + output = reserve1 > yNew ? reserve1 - yNew : 0; + } else { + // swap Y in and X out + yNew = reserve1 + amount; + if (yNew < y0) { + // remain on g() + xNew = CurveLib.f(yNew, py, px, y0, x0, cy); + } else { + // move to f() + xNew = CurveLib.fInverse(yNew, px, py, x0, y0, cx); + } + output = reserve0 > xNew ? reserve0 - xNew : 0; + } + } else { + // exact out + if (asset0IsInput) { + // swap Y out and X in + require(reserve1 > amount, SwapLimitExceeded()); + yNew = reserve1 - amount; + if (yNew < y0) { + // remain on g() + xNew = CurveLib.f(yNew, py, px, y0, x0, cy); + } else { + // move to f() + xNew = CurveLib.fInverse(yNew, px, py, x0, y0, cx); + } + output = xNew > reserve0 ? xNew - reserve0 : 0; + } else { + // swap X out and Y in + require(reserve0 > amount, SwapLimitExceeded()); + xNew = reserve0 - amount; + if (xNew < x0) { + // remain on f() + yNew = CurveLib.f(xNew, py, px, y0, x0, cx); + } else { + // move to g() + yNew = CurveLib.fInverse(xNew, py, px, y0, x0, cy); + } + output = yNew > reserve1 ? yNew - reserve1 : 0; + } + } + } +} diff --git a/src/UniswapHook.sol b/src/UniswapHook.sol new file mode 100644 index 0000000..e5db2dd --- /dev/null +++ b/src/UniswapHook.sol @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.27; + +import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; +import {BaseHook} from "v4-periphery/src/utils/BaseHook.sol"; +import {PoolKey} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; +import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; +import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; +import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; +import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol"; +import { + BeforeSwapDelta, toBeforeSwapDelta, BeforeSwapDeltaLibrary +} from "@uniswap/v4-core/src/types/BeforeSwapDelta.sol"; + +import {IEVault} from "evk/EVault/IEVault.sol"; + +import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; +import {CtxLib} from "./CtxLib.sol"; +import {QuoteLib} from "./QuoteLib.sol"; +import {CurveLib} from "./CurveLib.sol"; +import {FundsLib} from "./FundsLib.sol"; + +contract UniswapHook is BaseHook { + using SafeCast for uint256; + + address private immutable evc; + + PoolKey internal _poolKey; + + constructor(address evc_, address _poolManager) BaseHook(IPoolManager(_poolManager)) { + evc = evc_; + } + + function activateHook(IEulerSwap.Params memory p) internal { + address asset0Addr = IEVault(p.vault0).asset(); + address asset1Addr = IEVault(p.vault1).asset(); + + // convert fee in WAD to pips. 0.003e18 / 1e12 = 3000 = 0.30% + uint24 fee = uint24(p.fee / 1e12); + + _poolKey = PoolKey({ + currency0: Currency.wrap(asset0Addr), + currency1: Currency.wrap(asset1Addr), + fee: fee, + tickSpacing: 60, // TODO: fix arbitrary tick spacing + hooks: IHooks(address(this)) + }); + + // create the pool on v4, using starting price as sqrtPrice(1/1) * Q96 + poolManager.initialize(_poolKey, 79228162514264337593543950336); + } + + /// @dev Helper function to return the poolKey as its struct type + function poolKey() external view returns (PoolKey memory) { + return _poolKey; + } + + function _beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata) + internal + override + returns (bytes4, BeforeSwapDelta, uint24) + { + IEulerSwap.Params memory p = CtxLib.getParams(); + + uint256 amountInWithoutFee; + uint256 amountOut; + BeforeSwapDelta returnDelta; + + { + uint256 amountIn; + bool isExactInput = params.amountSpecified < 0; + if (isExactInput) { + amountIn = uint256(-params.amountSpecified); + amountOut = QuoteLib.computeQuote(evc, p, params.zeroForOne, uint256(-params.amountSpecified), true); + } else { + amountIn = QuoteLib.computeQuote(evc, p, params.zeroForOne, uint256(params.amountSpecified), false); + amountOut = uint256(params.amountSpecified); + } + + // return the delta to the PoolManager, so it can process the accounting + // exact input: + // specifiedDelta = positive, to offset the input token taken by the hook (negative delta) + // unspecifiedDelta = negative, to offset the credit of the output token paid by the hook (positive delta) + // exact output: + // specifiedDelta = negative, to offset the output token paid by the hook (positive delta) + // unspecifiedDelta = positive, to offset the input token taken by the hook (negative delta) + returnDelta = isExactInput + ? toBeforeSwapDelta(amountIn.toInt128(), -(amountOut.toInt128())) + : toBeforeSwapDelta(-(amountOut.toInt128()), amountIn.toInt128()); + + // take the input token, from the PoolManager to the Euler vault + // the debt will be paid by the swapper via the swap router + // TODO: can we optimize the transfer by pulling from PoolManager directly to Euler? + poolManager.take(params.zeroForOne ? key.currency0 : key.currency1, address(this), amountIn); + amountInWithoutFee = FundsLib.depositAssets(evc, p, params.zeroForOne ? p.vault0 : p.vault1); + + // pay the output token, to the PoolManager from an Euler vault + // the credit will be forwarded to the swap router, which then forwards it to the swapper + poolManager.sync(params.zeroForOne ? key.currency1 : key.currency0); + FundsLib.withdrawAssets(evc, p, params.zeroForOne ? p.vault1 : p.vault0, amountOut, address(poolManager)); + poolManager.settle(); + } + + { + CtxLib.Storage storage s = CtxLib.getStorage(); + + uint256 newReserve0 = params.zeroForOne ? (s.reserve0 + amountInWithoutFee) : (s.reserve0 - amountOut); + uint256 newReserve1 = !params.zeroForOne ? (s.reserve1 + amountInWithoutFee) : (s.reserve1 - amountOut); + + require(newReserve0 <= type(uint112).max && newReserve1 <= type(uint112).max, CurveLib.Overflow()); + require(CurveLib.verify(p, newReserve0, newReserve1), CurveLib.CurveViolation()); + + s.reserve0 = uint112(newReserve0); + s.reserve1 = uint112(newReserve1); + } + + return (BaseHook.beforeSwap.selector, returnDelta, 0); + } + + // TODO: fix salt mining & verification for the hook + function getHookPermissions() public pure override returns (Hooks.Permissions memory) {} + function validateHookAddress(BaseHook) internal pure override {} +} diff --git a/src/interfaces/IEulerSwap.sol b/src/interfaces/IEulerSwap.sol index 9adfbdc..c94558a 100644 --- a/src/interfaces/IEulerSwap.sol +++ b/src/interfaces/IEulerSwap.sol @@ -2,67 +2,65 @@ pragma solidity >=0.8.0; interface IEulerSwap { + /// @dev Immutable pool parameters. Passed to the instance via proxy trailing data. struct Params { + // Entities address vault0; address vault1; address eulerAccount; + // Curve uint112 equilibriumReserve0; uint112 equilibriumReserve1; - uint112 currReserve0; - uint112 currReserve1; - uint256 fee; - } - - struct CurveParams { uint256 priceX; uint256 priceY; uint256 concentrationX; uint256 concentrationY; + // Fees + uint256 fee; + uint256 protocolFee; + address protocolFeeRecipient; } - /// @notice Optimistically sends the requested amounts of tokens to the `to` - /// address, invokes `uniswapV2Call` callback on `to` (if `data` was provided), - /// and then verifies that a sufficient amount of tokens were transferred to - /// satisfy the swapping curve invariant. - function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; - - /// @notice Approves the vaults to access the EulerSwap instance's tokens, and enables - /// vaults as collateral. Can be invoked by anybody, and is harmless if invoked again. - /// Calling this function is optional: EulerSwap can be activated on the first swap. - function activate() external; + /// @dev Starting configuration of pool storage. + struct InitialState { + uint112 currReserve0; + uint112 currReserve1; + } - /// @notice Function that defines the shape of the swapping curve. Returns true iff - /// the specified reserve amounts would be acceptable (ie it is above and to-the-right - /// of the swapping curve). - function verify(uint256 newReserve0, uint256 newReserve1) external view returns (bool); + /// @notice Performs initial activation setup, such as approving vaults to access the + /// EulerSwap instance's tokens, enabling vaults as collateral, setting up Uniswap + /// hooks, etc. This should only be invoked by the factory. + function activate(InitialState calldata initialState) external; - /// @notice Returns the address of the Ethereum Vault Connector (EVC) used by this contract. - /// @return The address of the EVC contract. - function EVC() external view returns (address); + /// @notice Retrieves the pool's immutable parameters. + function getParams() external view returns (Params memory); - // EulerSwap Accessors + /// @notice Retrieves the underlying assets supported by this pool. + function getAssets() external view returns (address asset0, address asset1); - function curve() external view returns (bytes32); - function vault0() external view returns (address); - function vault1() external view returns (address); - function asset0() external view returns (address); - function asset1() external view returns (address); - function eulerAccount() external view returns (address); - function equilibriumReserve0() external view returns (uint112); - function equilibriumReserve1() external view returns (uint112); - function fee() external view returns (uint256); - function protocolFee() external view returns (uint256); - function protocolFeeRecipient() external view returns (address); - /// @notice Returns the current reserves of the pool + /// @notice Retrieves the current reserves from storage, along with the pool's lock status. /// @return reserve0 The amount of asset0 in the pool /// @return reserve1 The amount of asset1 in the pool /// @return status The status of the pool (0 = unactivated, 1 = unlocked, 2 = locked) function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 status); - // Curve Accessors + /// @notice Generates a quote for how much a given size swap will cost. + /// @param tokenIn The input token that the swapper SENDS + /// @param tokenOut The output token that the swapper GETS + /// @param amount The quantity of input or output tokens, for exact input and exact output swaps respectively + /// @param exactIn True if this is an exact input swap, false if exact output + /// @return The quoted quantity of output or input tokens, for exact input and exact output swaps respectively + function computeQuote(address tokenIn, address tokenOut, uint256 amount, bool exactIn) + external + view + returns (uint256); + + /// @notice Upper-bounds on the amounts of each token that this pool can currently support swaps for. + function getLimits(address tokenIn, address tokenOut) external view returns (uint256, uint256); - function priceX() external view returns (uint256); - function priceY() external view returns (uint256); - function concentrationX() external view returns (uint256); - function concentrationY() external view returns (uint256); + /// @notice Optimistically sends the requested amounts of tokens to the `to` + /// address, invokes `uniswapV2Call` callback on `to` (if `data` was provided), + /// and then verifies that a sufficient amount of tokens were transferred to + /// satisfy the swapping curve invariant. + function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; } diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol index 50b141b..d20c391 100644 --- a/src/interfaces/IEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -14,11 +14,11 @@ interface IEulerSwapFactory { /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from /// the euler account address and provided salt parameter. This allows the pool address to be /// predicted before deployment. - /// @param params Core pool parameters including vaults, account, and fee settings - /// @param curveParams Parameters defining the curve shape including prices and concentrations + /// @param params Core pool parameters including vaults, account, fees, and curve shape + /// @param initialState Initial state of the pool /// @param salt Unique value to generate deterministic pool address /// @return Address of the newly deployed pool - function deployPool(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams, bytes32 salt) + function deployPool(IEulerSwap.Params memory params, IEulerSwap.InitialState memory initialState, bytes32 salt) external returns (address); @@ -33,18 +33,9 @@ interface IEulerSwapFactory { /// the euler account address and provided salt parameter. This allows the pool address to be /// predicted before deployment. /// @param poolParams Core pool parameters including vaults, account, and fee settings - /// @param curveParams Parameters defining the curve shape including prices and concentrations /// @param salt Unique value to generate deterministic pool address /// @return Address of the newly deployed pool - function computePoolAddress( - IEulerSwap.Params memory poolParams, - IEulerSwap.CurveParams memory curveParams, - bytes32 salt - ) external view returns (address); - - /// @notice Returns the address of the Ethereum Vault Connector (EVC) contract - /// @return The address of the EVC contract - function EVC() external view returns (address); + function computePoolAddress(IEulerSwap.Params memory poolParams, bytes32 salt) external view returns (address); /// @notice Returns a slice of all deployed pools /// @dev Returns a subset of the pools array from start to end index diff --git a/src/interfaces/IEulerSwapPeriphery.sol b/src/interfaces/IEulerSwapPeriphery.sol index cb84b16..bc9337a 100644 --- a/src/interfaces/IEulerSwapPeriphery.sol +++ b/src/interfaces/IEulerSwapPeriphery.sol @@ -3,12 +3,30 @@ pragma solidity >=0.8.0; interface IEulerSwapPeriphery { /// @notice Swap `amountIn` of `tokenIn` for `tokenOut`, with at least `amountOutMin` received. - function swapExactIn(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin) - external; + /// Output tokens are sent to `receiver`. The swap will fail after `deadline` (unless `deadline` is 0). + /// IMPORTANT: `eulerSwap` must be a trusted contract, for example created by a trusted factory. + function swapExactIn( + address eulerSwap, + address tokenIn, + address tokenOut, + uint256 amountIn, + address receiver, + uint256 amountOutMin, + uint256 deadline + ) external; /// @notice Swap `amountOut` of `tokenOut` for `tokenIn`, with at most `amountInMax` paid. - function swapExactOut(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut, uint256 amountInMax) - external; + /// Output tokens are sent to `receiver`. The swap will fail after `deadline` (unless `deadline` is 0). + /// IMPORTANT: `eulerSwap` must be a trusted contract, for example created by a trusted factory. + function swapExactOut( + address eulerSwap, + address tokenIn, + address tokenOut, + uint256 amountOut, + address receiver, + uint256 amountInMax, + uint256 deadline + ) external; /// @notice How much `tokenOut` can I get for `amountIn` of `tokenIn`? function quoteExactInput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn) @@ -22,6 +40,6 @@ interface IEulerSwapPeriphery { view returns (uint256); - /// @notice Max amount the pool can buy of tokenIn and sell of tokenOut + /// @notice Upper-bound on the max amount that can be sold of tokenIn and bought of tokenOut function getLimits(address eulerSwap, address tokenIn, address tokenOut) external view returns (uint256, uint256); } diff --git a/test/EulerSwapTest.t.sol b/test/Basic.t.sol similarity index 99% rename from test/EulerSwapTest.t.sol rename to test/Basic.t.sol index 989fb4b..c208f5e 100644 --- a/test/EulerSwapTest.t.sol +++ b/test/Basic.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.24; import {IEVault, IEulerSwap, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; -contract EulerSwapTest is EulerSwapTestBase { +contract Basic is EulerSwapTestBase { EulerSwap public eulerSwap; function setUp() public virtual override { diff --git a/test/Ctx.t.sol b/test/Ctx.t.sol new file mode 100644 index 0000000..76bfd1b --- /dev/null +++ b/test/Ctx.t.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; + +import {EulerSwapTestBase, IEulerSwap} from "./EulerSwapTestBase.t.sol"; +import {CtxLib} from "../src/CtxLib.sol"; + +contract CtxTest is EulerSwapTestBase { + function setUp() public virtual override { + super.setUp(); + } + + function test_staticCtxStorage() public pure { + assertEq(CtxLib.CtxStorageLocation, keccak256("eulerSwap.storage")); + } + + function test_staticParamSize() public view { + IEulerSwap.Params memory params = getEulerSwapParams(1e18, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 0); + assertEq(abi.encode(params).length, 384); + } +} diff --git a/test/DepositFailures.t.sol b/test/DepositFailures.t.sol index a3f6290..c962c51 100644 --- a/test/DepositFailures.t.sol +++ b/test/DepositFailures.t.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.24; import {IEVault, IEulerSwap, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; import {IRMTestFixed} from "evk-test/mocks/IRMTestFixed.sol"; import {Errors as EVKErrors} from "evk/EVault/shared/Errors.sol"; +import {FundsLib} from "../src/FundsLib.sol"; import "evk/EVault/shared/Constants.sol" as EVKConstants; contract DepositFailuresTest is EulerSwapTestBase { @@ -76,7 +77,7 @@ contract DepositFailuresTest is EulerSwapTestBase { vm.expectRevert( abi.encodeWithSelector( - EulerSwap.DepositFailure.selector, abi.encodeWithSelector(EVKErrors.E_OperationDisabled.selector) + FundsLib.DepositFailure.selector, abi.encodeWithSelector(EVKErrors.E_OperationDisabled.selector) ) ); eulerSwap.swap(0, amountOut, address(this), ""); diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index ca52a2b..1e6ebc0 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -5,17 +5,17 @@ import {Test, console} from "forge-std/Test.sol"; import {EVaultTestBase, TestERC20, IRMTestDefault} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; import {IEulerSwap, IEVC, EulerSwap} from "../src/EulerSwap.sol"; +import {EulerSwapFactory} from "../src/EulerSwapFactory.sol"; import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; -import {EulerSwapHook} from "../src/EulerSwapHook.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {HookMiner} from "v4-periphery/src/utils/HookMiner.sol"; +import {HookMiner} from "./utils/HookMiner.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; +import {MetaProxyDeployer} from "../src/MetaProxyDeployer.sol"; contract EulerSwapTestBase is EVaultTestBase { uint256 public constant MAX_QUOTE_ERROR = 4; address public depositor = makeAddr("depositor"); - address public creator = makeAddr("creator"); address public holder = makeAddr("holder"); address public recipient = makeAddr("recipient"); address public anyone = makeAddr("anyone"); @@ -23,18 +23,38 @@ contract EulerSwapTestBase is EVaultTestBase { TestERC20 assetTST3; IEVault public eTST3; + address public eulerSwapImpl; + EulerSwapFactory public eulerSwapFactory; EulerSwapPeriphery public periphery; + uint256 currSalt = 0; + address installedOperator; + modifier monotonicHolderNAV() { int256 orig = getHolderNAV(); _; assertGe(getHolderNAV(), orig); } + function deployEulerSwap(address poolManager_) public { + eulerSwapImpl = address(new EulerSwap(address(evc), poolManager_)); + eulerSwapFactory = new EulerSwapFactory(address(evc), address(factory), eulerSwapImpl); + periphery = new EulerSwapPeriphery(); + } + + function removeInstalledOperator() public { + if (installedOperator == address(0)) return; + + vm.prank(holder); + evc.setAccountOperator(holder, installedOperator, false); + + installedOperator = address(0); + } + function setUp() public virtual override { super.setUp(); - periphery = new EulerSwapPeriphery(); + deployEulerSwap(address(0)); // Default is no poolManager // deploy more vaults assetTST3 = new TestERC20("Test Token 3", "TST3", 18, false); @@ -102,56 +122,65 @@ contract EulerSwapTestBase is EVaultTestBase { } function createEulerSwap( - uint112 debtLimitA, - uint112 debtLimitB, + uint112 reserve0, + uint112 reserve1, uint256 fee, uint256 px, uint256 py, uint256 cx, uint256 cy ) internal returns (EulerSwap) { - vm.prank(creator); - EulerSwap eulerSwap = new EulerSwap( - getEulerSwapParams(debtLimitA, debtLimitB, fee), - IEulerSwap.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}) - ); + removeInstalledOperator(); + + IEulerSwap.Params memory params = getEulerSwapParams(reserve0, reserve1, px, py, cx, cy, fee); + IEulerSwap.InitialState memory initialState = + IEulerSwap.InitialState({currReserve0: reserve0, currReserve1: reserve1}); + + bytes32 salt = bytes32(currSalt++); + + address predictedAddr = eulerSwapFactory.computePoolAddress(params, salt); + + vm.prank(holder); + evc.setAccountOperator(holder, predictedAddr, true); + installedOperator = predictedAddr; vm.prank(holder); - evc.setAccountOperator(holder, address(eulerSwap), true); + EulerSwap eulerSwap = EulerSwap(eulerSwapFactory.deployPool(params, initialState, salt)); return eulerSwap; } function createEulerSwapHook( - IPoolManager _poolManager, - uint112 debtLimitA, - uint112 debtLimitB, + uint112 reserve0, + uint112 reserve1, uint256 fee, uint256 px, uint256 py, uint256 cx, uint256 cy - ) internal returns (EulerSwapHook) { - IEulerSwap.Params memory poolParams = getEulerSwapParams(debtLimitA, debtLimitB, fee); - IEulerSwap.CurveParams memory curveParams = - IEulerSwap.CurveParams({priceX: px, priceY: py, concentrationX: cx, concentrationY: cy}); - - bytes memory constructorArgs = abi.encode(_poolManager, poolParams, curveParams); - (address hookAddress, bytes32 salt) = HookMiner.find( - creator, + ) internal returns (EulerSwap) { + removeInstalledOperator(); + + IEulerSwap.Params memory params = getEulerSwapParams(reserve0, reserve1, px, py, cx, cy, fee); + IEulerSwap.InitialState memory initialState = + IEulerSwap.InitialState({currReserve0: reserve0, currReserve1: reserve1}); + + bytes memory creationCode = MetaProxyDeployer.creationCodeMetaProxy(eulerSwapImpl, abi.encode(params)); + (address predictedAddr, bytes32 salt) = HookMiner.find( + address(eulerSwapFactory), + holder, uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG), - type(EulerSwapHook).creationCode, - constructorArgs + creationCode ); - vm.prank(creator); - EulerSwapHook eulerSwapHook = new EulerSwapHook{salt: salt}(_poolManager, poolParams, curveParams); - assertEq(address(eulerSwapHook), hookAddress); + vm.prank(holder); + evc.setAccountOperator(holder, predictedAddr, true); + installedOperator = predictedAddr; vm.prank(holder); - evc.setAccountOperator(holder, address(eulerSwapHook), true); + EulerSwap eulerSwap = EulerSwap(eulerSwapFactory.deployPool(params, initialState, salt)); - return eulerSwapHook; + return eulerSwap; } function mintAndDeposit(address who, IEVault vault, uint256 amount) internal { @@ -199,20 +228,28 @@ contract EulerSwapTestBase is EVaultTestBase { return skimmed; } - function getEulerSwapParams(uint112 reserve0, uint112 reserve1, uint256 fee) - internal - view - returns (EulerSwap.Params memory) - { + function getEulerSwapParams( + uint112 reserve0, + uint112 reserve1, + uint256 px, + uint256 py, + uint256 cx, + uint256 cy, + 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 + priceX: px, + priceY: py, + concentrationX: cx, + concentrationY: cy, + fee: fee, + protocolFee: 0, + protocolFeeRecipient: address(0) }); } diff --git a/test/EulerSwapFactoryTest.t.sol b/test/FactoryTest.t.sol similarity index 52% rename from test/EulerSwapFactoryTest.t.sol rename to test/FactoryTest.t.sol index ee8dda3..efb8242 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/FactoryTest.t.sol @@ -4,43 +4,50 @@ pragma solidity ^0.8.24; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; -import {HookMiner} from "../src/utils/HookMiner.sol"; +import {HookMiner} from "./utils/HookMiner.sol"; import {EulerSwapTestBase, IEulerSwap, IEVC, EulerSwap} from "./EulerSwapTestBase.t.sol"; import {EulerSwapFactory, IEulerSwapFactory} from "../src/EulerSwapFactory.sol"; -import {EulerSwapHook} from "../src/EulerSwapHook.sol"; +import {EulerSwap} from "../src/EulerSwap.sol"; +import {MetaProxyDeployer} from "../src/MetaProxyDeployer.sol"; -contract EulerSwapFactoryTest is EulerSwapTestBase { - EulerSwapFactory public eulerSwapFactory; +contract FactoryTest is EulerSwapTestBase { IPoolManager public poolManager; - uint256 minFee = 0.0000000000001e18; - function setUp() public virtual override { super.setUp(); - vm.startPrank(creator); - poolManager = PoolManagerDeployer.deploy(creator); - eulerSwapFactory = new EulerSwapFactory(poolManager, address(evc), address(factory)); - vm.stopPrank(); + poolManager = PoolManagerDeployer.deploy(address(this)); + + deployEulerSwap(address(poolManager)); assertEq(eulerSwapFactory.EVC(), address(evc)); } + function getBasicParams() + internal + view + returns (IEulerSwap.Params memory poolParams, IEulerSwap.InitialState memory initialState) + { + poolParams = getEulerSwapParams(1e18, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 0); + initialState = IEulerSwap.InitialState({currReserve0: 1e18, currReserve1: 1e18}); + } + + function mineSalt(IEulerSwap.Params memory poolParams) internal view returns (address hookAddress, bytes32 salt) { + uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG); + bytes memory creationCode = MetaProxyDeployer.creationCodeMetaProxy(eulerSwapImpl, abi.encode(poolParams)); + (hookAddress, salt) = HookMiner.find(address(eulerSwapFactory), holder, flags, creationCode); + } + function testDeployPool() public { uint256 allPoolsLengthBefore = eulerSwapFactory.poolsLength(); // test when new pool not set as operator - IEulerSwap.Params memory poolParams = - IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 0); - IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); + (IEulerSwap.Params memory poolParams, IEulerSwap.InitialState memory initialState) = getBasicParams(); - uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG); - bytes memory constructorArgs = abi.encode(poolManager, poolParams, curveParams); - (address hookAddress, bytes32 salt) = - HookMiner.find(address(eulerSwapFactory), holder, flags, type(EulerSwapHook).creationCode, constructorArgs); + (address hookAddress, bytes32 salt) = mineSalt(poolParams); - address predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); + address predictedAddress = eulerSwapFactory.computePoolAddress(poolParams, salt); assertEq(hookAddress, predictedAddress); IEVC.BatchItem[] memory items = new IEVC.BatchItem[](1); @@ -49,7 +56,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { onBehalfOfAccount: holder, targetContract: address(eulerSwapFactory), value: 0, - data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, initialState, salt)) }); vm.prank(holder); @@ -70,7 +77,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { onBehalfOfAccount: holder, targetContract: address(eulerSwapFactory), value: 0, - data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, initialState, salt)) }); vm.prank(holder); @@ -87,8 +94,8 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { assertEq(poolsList[0], address(eulerSwap)); // revert when attempting to deploy a new pool (with a different salt) - (address newHookAddress, bytes32 newSalt) = - HookMiner.find(address(eulerSwapFactory), holder, flags, type(EulerSwapHook).creationCode, constructorArgs); + poolParams.fee = 1; + (address newHookAddress, bytes32 newSalt) = mineSalt(poolParams); assertNotEq(newHookAddress, hookAddress); assertNotEq(newSalt, salt); @@ -97,7 +104,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { onBehalfOfAccount: holder, targetContract: address(eulerSwapFactory), value: 0, - data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, newSalt)) + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, initialState, newSalt)) }); vm.prank(holder); @@ -112,9 +119,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { function testDeployWithInvalidVaultImplementation() public { bytes32 salt = bytes32(uint256(1234)); - IEulerSwap.Params memory poolParams = - IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 0); - IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); + (IEulerSwap.Params memory poolParams, IEulerSwap.InitialState memory initialState) = getBasicParams(); // Create a fake vault that's not deployed by the factory address fakeVault = address(0x1234); @@ -123,64 +128,64 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { vm.prank(holder); vm.expectRevert(EulerSwapFactory.InvalidVaultImplementation.selector); - eulerSwapFactory.deployPool(poolParams, curveParams, salt); + eulerSwapFactory.deployPool(poolParams, initialState, salt); } function testDeployWithUnauthorizedCaller() public { bytes32 salt = bytes32(uint256(1234)); - IEulerSwap.Params memory poolParams = - IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 0); - IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); + (IEulerSwap.Params memory poolParams, IEulerSwap.InitialState memory initialState) = getBasicParams(); // Call from a different address than the euler account vm.prank(address(0x1234)); vm.expectRevert(EulerSwapFactory.Unauthorized.selector); - eulerSwapFactory.deployPool(poolParams, curveParams, salt); + eulerSwapFactory.deployPool(poolParams, initialState, salt); } function testDeployWithAssetsOutOfOrderOrEqual() public { - bytes32 salt = bytes32(uint256(1234)); - IEulerSwap.Params memory poolParams = - IEulerSwap.Params(address(eTST), address(eTST), holder, 1e18, 1e18, 1e18, 1e18, 0); - IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); + (IEulerSwap.Params memory poolParams, IEulerSwap.InitialState memory initialState) = getBasicParams(); + (poolParams.vault0, poolParams.vault1) = (poolParams.vault1, poolParams.vault0); + + (address hookAddress, bytes32 salt) = mineSalt(poolParams); + + vm.prank(holder); + evc.setAccountOperator(holder, hookAddress, true); vm.prank(holder); vm.expectRevert(EulerSwap.AssetsOutOfOrderOrEqual.selector); - eulerSwapFactory.deployPool(poolParams, curveParams, salt); + eulerSwapFactory.deployPool(poolParams, initialState, salt); } function testDeployWithBadFee() public { - bytes32 salt = bytes32(uint256(1234)); - IEulerSwap.Params memory poolParams = - IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 1e18); - IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); + (IEulerSwap.Params memory poolParams, IEulerSwap.InitialState memory initialState) = getBasicParams(); + poolParams.fee = 1e18; + + (address hookAddress, bytes32 salt) = mineSalt(poolParams); + + vm.prank(holder); + evc.setAccountOperator(holder, hookAddress, true); vm.prank(holder); vm.expectRevert(EulerSwap.BadParam.selector); - eulerSwapFactory.deployPool(poolParams, curveParams, salt); + eulerSwapFactory.deployPool(poolParams, initialState, salt); } function testPoolsByPair() public { // First deploy a pool - bytes32 salt = bytes32(uint256(1234)); - IEulerSwap.Params memory poolParams = - IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 0); - IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); - - address predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); + (IEulerSwap.Params memory poolParams, IEulerSwap.InitialState memory initialState) = getBasicParams(); + (address hookAddress, bytes32 salt) = mineSalt(poolParams); IEVC.BatchItem[] memory items = new IEVC.BatchItem[](2); items[0] = IEVC.BatchItem({ onBehalfOfAccount: address(0), targetContract: address(evc), value: 0, - data: abi.encodeCall(evc.setAccountOperator, (holder, predictedAddress, true)) + data: abi.encodeCall(evc.setAccountOperator, (holder, hookAddress, true)) }); items[1] = IEVC.BatchItem({ onBehalfOfAccount: holder, targetContract: address(eulerSwapFactory), value: 0, - data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, initialState, salt)) }); vm.prank(holder); @@ -188,8 +193,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { // Get the deployed pool and its assets address pool = eulerSwapFactory.poolByEulerAccount(holder); - address asset0 = EulerSwap(pool).asset0(); - address asset1 = EulerSwap(pool).asset1(); + (address asset0, address asset1) = EulerSwap(pool).getAssets(); // Test poolsByPairLength assertEq(eulerSwapFactory.poolsByPairLength(asset0, asset1), 1); @@ -197,47 +201,21 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { // Test poolsByPairSlice address[] memory slice = eulerSwapFactory.poolsByPairSlice(asset0, asset1, 0, 1); assertEq(slice.length, 1); - assertEq(slice[0], predictedAddress); + assertEq(slice[0], hookAddress); // Test poolsByPair address[] memory pools = eulerSwapFactory.poolsByPair(asset0, asset1); assertEq(pools.length, 1); - assertEq(pools[0], predictedAddress); + assertEq(pools[0], hookAddress); } - function testComputePoolAddress() public view { - bytes32 salt = bytes32(uint256(1234)); - IEulerSwap.Params memory poolParams = - IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 1e18, 0); - IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); + function testCallImpl() public { + // Underlying implementation is locked: must call via a proxy - address predictedAddress = eulerSwapFactory.computePoolAddress(poolParams, curveParams, salt); - assertEq(predictedAddress, predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt)); - } + vm.expectRevert(EulerSwap.AlreadyActivated.selector); + EulerSwap(eulerSwapImpl).activate(IEulerSwap.InitialState({currReserve0: 1e18, currReserve1: 1e18})); - function predictPoolAddress( - address factoryAddress, - IEulerSwap.Params memory poolParams, - IEulerSwap.CurveParams memory curveParams, - bytes32 salt - ) internal view returns (address) { - return address( - uint160( - uint256( - keccak256( - abi.encodePacked( - bytes1(0xff), - factoryAddress, - keccak256(abi.encode(address(poolParams.eulerAccount), salt)), - keccak256( - abi.encodePacked( - type(EulerSwapHook).creationCode, abi.encode(poolManager, poolParams, curveParams) - ) - ) - ) - ) - ) - ) - ); + vm.expectRevert(EulerSwap.Locked.selector); + EulerSwap(eulerSwapImpl).getReserves(); } } diff --git a/test/Fees.t.sol b/test/Fees.t.sol index 6bd6abc..635b049 100644 --- a/test/Fees.t.sol +++ b/test/Fees.t.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.24; import {Test, console} from "forge-std/Test.sol"; import {IEVault, IEulerSwap, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; +import {CurveLib} from "../src/CurveLib.sol"; contract FeesTest is EulerSwapTestBase { EulerSwap public eulerSwap; @@ -40,7 +41,7 @@ contract FeesTest is EulerSwapTestBase { // Pulling out one extra reverts... - vm.expectRevert(EulerSwap.CurveViolation.selector); + vm.expectRevert(CurveLib.CurveViolation.selector); eulerSwap.swap(0, amountOut + MAX_QUOTE_ERROR + 1, address(this), ""); // Just right: @@ -91,7 +92,7 @@ contract FeesTest is EulerSwapTestBase { // Pulling out one extra reverts... - vm.expectRevert(EulerSwap.CurveViolation.selector); + vm.expectRevert(CurveLib.CurveViolation.selector); eulerSwap.swap(0, amountOut + MAX_QUOTE_ERROR + 1, address(this), ""); // Just right: diff --git a/test/EulerSwapHook.fees.t.sol b/test/HookFees.t.sol similarity index 93% rename from test/EulerSwapHook.fees.t.sol rename to test/HookFees.t.sol index 71d49b3..6989143 100644 --- a/test/EulerSwapHook.fees.t.sol +++ b/test/HookFees.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.24; import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol"; import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; -import {EulerSwapHook} from "../src/EulerSwapHook.sol"; +import {EulerSwap} from "../src/EulerSwap.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {IPoolManager, PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol"; @@ -14,10 +14,10 @@ import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; -contract EulerSwapHookTest is EulerSwapTestBase { +contract HookFeesTest is EulerSwapTestBase { using StateLibrary for IPoolManager; - EulerSwapHook public eulerSwap; + EulerSwap public eulerSwap; IPoolManager public poolManager; PoolSwapTest public swapRouter; @@ -32,9 +32,10 @@ contract EulerSwapHookTest is EulerSwapTestBase { swapRouter = new PoolSwapTest(poolManager); minimalRouter = new MinimalRouter(poolManager); + deployEulerSwap(address(poolManager)); + // set swap fee to 10 bips - eulerSwap = createEulerSwapHook(poolManager, 60e18, 60e18, 0.001e18, 1e18, 1e18, 0.4e18, 0.85e18); - eulerSwap.activate(); + eulerSwap = createEulerSwapHook(60e18, 60e18, 0.001e18, 1e18, 1e18, 0.4e18, 0.85e18); // confirm pool was created assertFalse(eulerSwap.poolKey().currency1 == CurrencyLibrary.ADDRESS_ZERO); @@ -47,7 +48,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { (uint112 r0, uint112 r1,) = eulerSwap.getReserves(); uint256 amountIn = 1e18; - uint256 amountInWithoutFee = amountIn - (amountIn * eulerSwap.fee() / 1e18); + uint256 amountInWithoutFee = amountIn - (amountIn * eulerSwap.getParams().fee / 1e18); uint256 amountOut = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); @@ -89,7 +90,7 @@ contract EulerSwapHookTest is EulerSwapTestBase { periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), amountOut); // inverse of the fee math in Periphery - uint256 amountInWithoutFee = amountIn * (1e18 - eulerSwap.fee()) / 1e18; + uint256 amountInWithoutFee = amountIn * (1e18 - eulerSwap.getParams().fee) / 1e18; assetTST.mint(anyone, amountIn); diff --git a/test/EulerSwapHook.swaps.t.sol b/test/HookSwaps.t.sol similarity index 95% rename from test/EulerSwapHook.swaps.t.sol rename to test/HookSwaps.t.sol index 2cd8ad8..c8e5e30 100644 --- a/test/EulerSwapHook.swaps.t.sol +++ b/test/HookSwaps.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.24; import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol"; import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; -import {EulerSwapHook} from "../src/EulerSwapHook.sol"; +import {EulerSwap} from "../src/EulerSwap.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {IPoolManager, PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol"; @@ -14,10 +14,10 @@ import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; -contract EulerSwapHookTest is EulerSwapTestBase { +contract HookSwapsTest is EulerSwapTestBase { using StateLibrary for IPoolManager; - EulerSwapHook public eulerSwap; + EulerSwap public eulerSwap; IPoolManager public poolManager; PoolSwapTest public swapRouter; @@ -32,8 +32,9 @@ contract EulerSwapHookTest is EulerSwapTestBase { swapRouter = new PoolSwapTest(poolManager); minimalRouter = new MinimalRouter(poolManager); - eulerSwap = createEulerSwapHook(poolManager, 60e18, 60e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); - eulerSwap.activate(); + deployEulerSwap(address(poolManager)); + + eulerSwap = createEulerSwapHook(60e18, 60e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); // confirm pool was created assertFalse(eulerSwap.poolKey().currency1 == CurrencyLibrary.ADDRESS_ZERO); diff --git a/test/Limits.t.sol b/test/Limits.t.sol index 6e7e6d9..e6e3c47 100644 --- a/test/Limits.t.sol +++ b/test/Limits.t.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.24; import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol"; +import {QuoteLib} from "../src/QuoteLib.sol"; contract LimitsTest is EulerSwapTestBase { EulerSwap public eulerSwap; @@ -27,15 +28,15 @@ contract LimitsTest is EulerSwapTestBase { quote = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), 59.9999999e18); assertApproxEqAbs(quote, 3.6e27, 0.1e27); - vm.expectRevert(EulerSwapPeriphery.SwapLimitExceeded.selector); + vm.expectRevert(QuoteLib.SwapLimitExceeded.selector); quote = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), 60e18); - vm.expectRevert(EulerSwapPeriphery.SwapLimitExceeded.selector); + vm.expectRevert(QuoteLib.SwapLimitExceeded.selector); quote = periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), 60.000001e18); // Exact input - vm.expectRevert(EulerSwapPeriphery.SwapLimitExceeded.selector); + vm.expectRevert(QuoteLib.SwapLimitExceeded.selector); quote = periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), type(uint112).max); } @@ -56,7 +57,7 @@ contract LimitsTest is EulerSwapTestBase { assertEq(inLimit, 0); // cap exceeded assertEq(outLimit, 60e18); - vm.expectRevert(EulerSwapPeriphery.SwapLimitExceeded.selector); + vm.expectRevert(QuoteLib.SwapLimitExceeded.selector); periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), 1); } @@ -83,7 +84,7 @@ contract LimitsTest is EulerSwapTestBase { periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), 161.9999e18); assertApproxEqAbs(quote, 56.9e18, 0.1e18); - vm.expectRevert(EulerSwapPeriphery.SwapLimitExceeded.selector); + vm.expectRevert(QuoteLib.SwapLimitExceeded.selector); periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), 162e18 + 1); } diff --git a/test/EulerSwapPeriphery.t.sol b/test/Periphery.t.sol similarity index 51% rename from test/EulerSwapPeriphery.t.sol rename to test/Periphery.t.sol index cf5398d..46a14a2 100644 --- a/test/EulerSwapPeriphery.t.sol +++ b/test/Periphery.t.sol @@ -2,22 +2,14 @@ pragma solidity ^0.8.24; import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol"; -import {EulerSwapHarness} from "./harness/EulerSwapHarness.sol"; -contract EulerSwapPeripheryTest is EulerSwapTestBase { +contract PeripheryTest is EulerSwapTestBase { EulerSwap public eulerSwap; - EulerSwapHarness public eulerSwapHarness; function setUp() public virtual override { super.setUp(); eulerSwap = createEulerSwap(60e18, 60e18, 0, 1e18, 1e18, 0.4e18, 0.85e18); - - IEulerSwap.Params memory params = getEulerSwapParams(50e18, 50e18, 0.4e18); - IEulerSwap.CurveParams memory curveParams = - IEulerSwap.CurveParams({priceX: 1e18, priceY: 1e18, concentrationX: 0.85e18, concentrationY: 0.85e18}); - - eulerSwapHarness = new EulerSwapHarness(params, curveParams); // Use the mock EulerSwap contract with a public f() function } function test_SwapExactIn() public { @@ -29,7 +21,7 @@ contract EulerSwapPeripheryTest is EulerSwapTestBase { vm.startPrank(anyone); assetTST.approve(address(periphery), amountIn); - periphery.swapExactIn(address(eulerSwap), address(assetTST), address(assetTST2), amountIn, amountOut); + periphery.swapExactIn(address(eulerSwap), address(assetTST), address(assetTST2), amountIn, anyone, amountOut, 0); vm.stopPrank(); assertEq(assetTST2.balanceOf(anyone), amountOut); @@ -45,7 +37,9 @@ contract EulerSwapPeripheryTest is EulerSwapTestBase { vm.startPrank(anyone); assetTST.approve(address(periphery), amountIn); vm.expectRevert(EulerSwapPeriphery.AmountOutLessThanMin.selector); - periphery.swapExactIn(address(eulerSwap), address(assetTST), address(assetTST2), amountIn, amountOut + 1); + periphery.swapExactIn( + address(eulerSwap), address(assetTST), address(assetTST2), amountIn, anyone, amountOut + 1, 0 + ); vm.stopPrank(); } @@ -58,7 +52,9 @@ contract EulerSwapPeripheryTest is EulerSwapTestBase { vm.startPrank(anyone); assetTST.approve(address(periphery), amountIn); - periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut, amountIn); + periphery.swapExactOut( + address(eulerSwap), address(assetTST), address(assetTST2), amountOut, anyone, amountIn, 0 + ); vm.stopPrank(); assertEq(assetTST2.balanceOf(anyone), amountOut); @@ -74,7 +70,54 @@ contract EulerSwapPeripheryTest is EulerSwapTestBase { vm.startPrank(anyone); assetTST.approve(address(periphery), amountIn); vm.expectRevert(EulerSwapPeriphery.AmountInMoreThanMax.selector); - periphery.swapExactOut(address(eulerSwap), address(assetTST), address(assetTST2), amountOut * 2, amountIn); + periphery.swapExactOut( + address(eulerSwap), address(assetTST), address(assetTST2), amountOut * 2, anyone, amountIn, 0 + ); + vm.stopPrank(); + } + + function test_SwapAltReceiver() public { + address altReceiver = address(1234); + + uint256 amountIn = 1e18; + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(periphery), amountIn); + periphery.swapExactIn( + address(eulerSwap), address(assetTST), address(assetTST2), amountIn, altReceiver, amountOut, 0 + ); vm.stopPrank(); + + assertEq(assetTST2.balanceOf(anyone), 0); + assertEq(assetTST2.balanceOf(altReceiver), amountOut); + } + + function test_SwapDeadline() public { + skip(1000); + + uint256 amountIn = 1e18; + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(periphery), amountIn); + + vm.expectRevert(EulerSwapPeriphery.DeadlineExpired.selector); + periphery.swapExactIn( + address(eulerSwap), address(assetTST), address(assetTST2), amountIn, anyone, amountOut, block.timestamp - 1 + ); + + periphery.swapExactIn( + address(eulerSwap), address(assetTST), address(assetTST2), amountIn, anyone, amountOut, block.timestamp + 1 + ); + vm.stopPrank(); + + assertEq(assetTST2.balanceOf(anyone), amountOut); } } diff --git a/test/harness/EulerSwapHarness.sol b/test/harness/EulerSwapHarness.sol deleted file mode 100644 index 88801d0..0000000 --- a/test/harness/EulerSwapHarness.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.27; - -import {EulerSwap, IEulerSwap} from "../../src/EulerSwap.sol"; - -contract EulerSwapHarness is EulerSwap { - constructor(IEulerSwap.Params memory params, IEulerSwap.CurveParams memory curveParams) - EulerSwap(params, curveParams) - {} - - /// @notice Exposes the internal f() function as a public function for testing - function exposedF(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) - external - pure - returns (uint256) - { - return f(x, px, py, x0, y0, c); - } -} diff --git a/src/utils/HookMiner.sol b/test/utils/HookMiner.sol similarity index 58% rename from src/utils/HookMiner.sol rename to test/utils/HookMiner.sol index 5b98dbe..0bcdf88 100644 --- a/src/utils/HookMiner.sol +++ b/test/utils/HookMiner.sol @@ -14,25 +14,21 @@ library HookMiner { uint256 constant MAX_LOOP = 160_444; /// @notice Find a salt that produces a hook address with the desired `flags` - /// @param deployer The address that will deploy the hook. In `forge test`, this will be the test contract `address(this)` or the pranking address - /// In `forge script`, this should be `0x4e59b44847b379578588920cA78FbF26c0B4956C` (CREATE2 Deployer Proxy) + /// @param deployer The address that will deploy the hook. Typically the EulerSwapFactory. + /// @param account The account that is invoking the factory. /// @param flags The desired flags for the hook address. Example `uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.AFTER_SWAP_FLAG | ...)` /// @param creationCode The creation code of a hook contract. Example: `type(Counter).creationCode` - /// @param constructorArgs The encoded constructor arguments of a hook contract. Example: `abi.encode(address(manager))` /// @return (hookAddress, salt) The hook deploys to `hookAddress` when using `salt` with the syntax: `new Hook{salt: salt}()` - function find( - address deployer, - address account, - uint160 flags, - bytes memory creationCode, - bytes memory constructorArgs - ) internal view returns (address, bytes32) { + function find(address deployer, address account, uint160 flags, bytes memory creationCode) + internal + view + returns (address, bytes32) + { flags = flags & FLAG_MASK; // mask for only the bottom 14 bits - bytes memory creationCodeWithArgs = abi.encodePacked(creationCode, constructorArgs); address hookAddress; for (uint256 salt; salt < MAX_LOOP; salt++) { - hookAddress = computeAddress(deployer, account, salt, creationCodeWithArgs); + hookAddress = computeAddress(deployer, account, salt, creationCode); // if the hook's bottom 14 bits match the desired flags AND the address does not have bytecode, we found a match if (uint160(hookAddress) & FLAG_MASK == flags && hookAddress.code.length == 0) { @@ -43,11 +39,11 @@ library HookMiner { } /// @notice Precompute a contract address deployed via CREATE2 - /// @param deployer The address that will deploy the hook. In `forge test`, this will be the test contract `address(this)` or the pranking address - /// In `forge script`, this should be `0x4e59b44847b379578588920cA78FbF26c0B4956C` (CREATE2 Deployer Proxy) + /// @param deployer The address that will deploy the hook. Typically the EulerSwapFactory. + /// @param account The account that is invoking the factory. /// @param salt The salt used to deploy the hook - /// @param creationCodeWithArgs The creation code of a hook contract, with encoded constructor arguments appended. Example: `abi.encodePacked(type(Counter).creationCode, abi.encode(constructorArg1, constructorArg2))` - function computeAddress(address deployer, address account, uint256 salt, bytes memory creationCodeWithArgs) + /// @param creationCode The creation code of a hook contract. + function computeAddress(address deployer, address account, uint256 salt, bytes memory creationCode) internal pure returns (address hookAddress) @@ -57,10 +53,7 @@ library HookMiner { uint256( keccak256( abi.encodePacked( - bytes1(0xFF), - deployer, - keccak256(abi.encode(account, salt)), - keccak256(creationCodeWithArgs) + bytes1(0xFF), deployer, keccak256(abi.encode(account, salt)), keccak256(creationCode) ) ) ) From 650d4ae0933ab99cd22aac8d2863bea5bb7bed12 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Mon, 14 Apr 2025 22:36:07 +0100 Subject: [PATCH 258/312] remove todo that will not be done --- src/UniswapHook.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/src/UniswapHook.sol b/src/UniswapHook.sol index e5db2dd..1c41639 100644 --- a/src/UniswapHook.sol +++ b/src/UniswapHook.sol @@ -90,7 +90,6 @@ contract UniswapHook is BaseHook { // take the input token, from the PoolManager to the Euler vault // the debt will be paid by the swapper via the swap router - // TODO: can we optimize the transfer by pulling from PoolManager directly to Euler? poolManager.take(params.zeroForOne ? key.currency0 : key.currency1, address(this), amountIn); amountInWithoutFee = FundsLib.depositAssets(evc, p, params.zeroForOne ? p.vault0 : p.vault1); From ef7a7a07547f2f71b2c9c93cd2469b58ded9c08d Mon Sep 17 00:00:00 2001 From: saucepoint Date: Mon, 14 Apr 2025 22:41:06 +0100 Subject: [PATCH 259/312] hard code tick spacing to an easy sentinel value --- src/UniswapHook.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UniswapHook.sol b/src/UniswapHook.sol index 1c41639..f21bf62 100644 --- a/src/UniswapHook.sol +++ b/src/UniswapHook.sol @@ -42,7 +42,7 @@ contract UniswapHook is BaseHook { currency0: Currency.wrap(asset0Addr), currency1: Currency.wrap(asset1Addr), fee: fee, - tickSpacing: 60, // TODO: fix arbitrary tick spacing + tickSpacing: 1, // hard-coded tick spacing, as its unused hooks: IHooks(address(this)) }); From d79342df466b11559ded59480ed05ace564afd06 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Mon, 14 Apr 2025 23:44:55 +0100 Subject: [PATCH 260/312] add hook address validation; fix test implementation --- src/UniswapHook.sol | 21 ++++++++++++++++++--- test/EulerSwapTestBase.t.sol | 11 ++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/UniswapHook.sol b/src/UniswapHook.sol index f21bf62..46a60b8 100644 --- a/src/UniswapHook.sol +++ b/src/UniswapHook.sol @@ -116,7 +116,22 @@ contract UniswapHook is BaseHook { return (BaseHook.beforeSwap.selector, returnDelta, 0); } - // TODO: fix salt mining & verification for the hook - function getHookPermissions() public pure override returns (Hooks.Permissions memory) {} - function validateHookAddress(BaseHook) internal pure override {} + function getHookPermissions() public pure override returns (Hooks.Permissions memory) { + return Hooks.Permissions({ + beforeInitialize: false, + afterInitialize: false, + beforeAddLiquidity: false, + afterAddLiquidity: false, + beforeRemoveLiquidity: false, + afterRemoveLiquidity: false, + beforeSwap: true, + afterSwap: false, + beforeDonate: false, + afterDonate: false, + beforeSwapReturnDelta: true, + afterSwapReturnDelta: false, + afterAddLiquidityReturnDelta: false, + afterRemoveLiquidityReturnDelta: false + }); + } } diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index 1e6ebc0..1ee4b9d 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -9,6 +9,7 @@ import {EulerSwapFactory} from "../src/EulerSwapFactory.sol"; import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {HookMiner} from "./utils/HookMiner.sol"; +import {HookMiner as v4HookMiner} from "v4-periphery/src/utils/HookMiner.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; import {MetaProxyDeployer} from "../src/MetaProxyDeployer.sol"; @@ -37,7 +38,15 @@ contract EulerSwapTestBase is EVaultTestBase { } function deployEulerSwap(address poolManager_) public { - eulerSwapImpl = address(new EulerSwap(address(evc), poolManager_)); + // use the canonical miner to find a valid 'implementation' address + (, bytes32 salt) = v4HookMiner.find( + address(this), + uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG), + type(EulerSwap).creationCode, + abi.encode(address(evc), poolManager_) + ); + + eulerSwapImpl = address(new EulerSwap{salt: salt}(address(evc), poolManager_)); eulerSwapFactory = new EulerSwapFactory(address(evc), address(factory), eulerSwapImpl); periphery = new EulerSwapPeriphery(); } From ba4b294cf59cc1c33db6172a5e934855aef8b611 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Mon, 14 Apr 2025 23:45:51 +0100 Subject: [PATCH 261/312] updated note --- TODO | 1 - 1 file changed, 1 deletion(-) diff --git a/TODO b/TODO index c243361..889a0f4 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,6 @@ ! document that periphery depends on non-malicious eulerSwap instances ! limitations of getLimits * update deploy scripts -* TODOs in UniswapHook.sol * small cleanups in CurveLib ? tighten up getLimits bounds From 40db263f5919298144205a3e9c6c79a6ed1aed0b Mon Sep 17 00:00:00 2001 From: saucepoint Date: Tue, 15 Apr 2025 00:41:00 +0100 Subject: [PATCH 262/312] revert on CLAMM liquidity; updated flags --- src/UniswapHook.sol | 13 ++++++++++++- test/EulerSwapTestBase.t.sol | 4 ++-- test/FactoryTest.t.sol | 3 ++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/UniswapHook.sol b/src/UniswapHook.sol index 46a60b8..45f94de 100644 --- a/src/UniswapHook.sol +++ b/src/UniswapHook.sol @@ -27,6 +27,8 @@ contract UniswapHook is BaseHook { PoolKey internal _poolKey; + error NativeConcentratedLiquidityUnsupported(); + constructor(address evc_, address _poolManager) BaseHook(IPoolManager(_poolManager)) { evc = evc_; } @@ -116,11 +118,20 @@ contract UniswapHook is BaseHook { return (BaseHook.beforeSwap.selector, returnDelta, 0); } + function _beforeAddLiquidity(address, PoolKey calldata, IPoolManager.ModifyLiquidityParams calldata, bytes calldata) + internal + pure + override + returns (bytes4) + { + revert NativeConcentratedLiquidityUnsupported(); + } + function getHookPermissions() public pure override returns (Hooks.Permissions memory) { return Hooks.Permissions({ beforeInitialize: false, afterInitialize: false, - beforeAddLiquidity: false, + beforeAddLiquidity: true, afterAddLiquidity: false, beforeRemoveLiquidity: false, afterRemoveLiquidity: false, diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index 1ee4b9d..c15084f 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -41,7 +41,7 @@ contract EulerSwapTestBase is EVaultTestBase { // use the canonical miner to find a valid 'implementation' address (, bytes32 salt) = v4HookMiner.find( address(this), - uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG), + uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG), type(EulerSwap).creationCode, abi.encode(address(evc), poolManager_) ); @@ -178,7 +178,7 @@ contract EulerSwapTestBase is EVaultTestBase { (address predictedAddr, bytes32 salt) = HookMiner.find( address(eulerSwapFactory), holder, - uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG), + uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG), creationCode ); diff --git a/test/FactoryTest.t.sol b/test/FactoryTest.t.sol index efb8242..7703acc 100644 --- a/test/FactoryTest.t.sol +++ b/test/FactoryTest.t.sol @@ -33,7 +33,8 @@ contract FactoryTest is EulerSwapTestBase { } function mineSalt(IEulerSwap.Params memory poolParams) internal view returns (address hookAddress, bytes32 salt) { - uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG); + uint160 flags = + uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG); bytes memory creationCode = MetaProxyDeployer.creationCodeMetaProxy(eulerSwapImpl, abi.encode(poolParams)); (hookAddress, salt) = HookMiner.find(address(eulerSwapFactory), holder, flags, creationCode); } From 4c757b05d8ff20211d8d0e5f3ad2500555a2f515 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Tue, 15 Apr 2025 00:41:27 +0100 Subject: [PATCH 263/312] test that v3 CLAMM reverts --- test/HookSwaps.t.sol | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/HookSwaps.t.sol b/test/HookSwaps.t.sol index c8e5e30..fc0824e 100644 --- a/test/HookSwaps.t.sol +++ b/test/HookSwaps.t.sol @@ -4,15 +4,20 @@ pragma solidity ^0.8.24; import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol"; import {TestERC20} from "evk-test/unit/evault/EVaultTestBase.t.sol"; import {EulerSwap} from "../src/EulerSwap.sol"; +import {UniswapHook} from "../src/UniswapHook.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {IPoolManager, PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol"; import {PoolSwapTest} from "@uniswap/v4-core/src/test/PoolSwapTest.sol"; import {MinimalRouter} from "./utils/MinimalRouter.sol"; +import {PoolModifyLiquidityTest} from "@uniswap/v4-core/src/test/PoolModifyLiquidityTest.sol"; import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; +import {CustomRevert} from "@uniswap/v4-core/src/libraries/CustomRevert.sol"; +import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; +import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; contract HookSwapsTest is EulerSwapTestBase { using StateLibrary for IPoolManager; @@ -22,6 +27,7 @@ contract HookSwapsTest is EulerSwapTestBase { IPoolManager public poolManager; PoolSwapTest public swapRouter; MinimalRouter public minimalRouter; + PoolModifyLiquidityTest public liquidityManager; PoolSwapTest.TestSettings public settings = PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}); @@ -31,6 +37,7 @@ contract HookSwapsTest is EulerSwapTestBase { poolManager = PoolManagerDeployer.deploy(address(this)); swapRouter = new PoolSwapTest(poolManager); minimalRouter = new MinimalRouter(poolManager); + liquidityManager = new PoolModifyLiquidityTest(poolManager); deployEulerSwap(address(poolManager)); @@ -119,6 +126,35 @@ contract HookSwapsTest is EulerSwapTestBase { vm.stopPrank(); } + /// @dev adding liquidity as a concentrated liquidity position will revert + function test_revertAddConcentratedLiquidity() public { + assetTST.mint(anyone, 10000e18); + assetTST2.mint(anyone, 10000e18); + + vm.startPrank(anyone); + assetTST.approve(address(liquidityManager), 1e18); + assetTST2.approve(address(liquidityManager), 1e18); + + PoolKey memory poolKey = eulerSwap.poolKey(); + + // hook intentionally reverts to prevent v3-CLAMM positions + vm.expectRevert( + abi.encodeWithSelector( + CustomRevert.WrappedError.selector, + address(eulerSwap), + IHooks.beforeAddLiquidity.selector, + abi.encodeWithSelector(UniswapHook.NativeConcentratedLiquidityUnsupported.selector), + abi.encodeWithSelector(Hooks.HookCallFailed.selector) + ) + ); + liquidityManager.modifyLiquidity( + poolKey, + IPoolManager.ModifyLiquidityParams({tickLower: -10, tickUpper: 10, liquidityDelta: 1000, salt: bytes32(0)}), + "" + ); + vm.stopPrank(); + } + function _swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount) internal { IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ zeroForOne: zeroForOne, From 503245f8bd8eb020ec375a15a63cf01d2d20bded Mon Sep 17 00:00:00 2001 From: saucepoint Date: Tue, 15 Apr 2025 16:59:33 +0100 Subject: [PATCH 264/312] updated audit note --- docs/audits/EulerSwapHook_Audit_Scope.md | 33 ++++++++++++++---------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/docs/audits/EulerSwapHook_Audit_Scope.md b/docs/audits/EulerSwapHook_Audit_Scope.md index 8d31df3..2f6b08f 100644 --- a/docs/audits/EulerSwapHook_Audit_Scope.md +++ b/docs/audits/EulerSwapHook_Audit_Scope.md @@ -2,7 +2,7 @@ Through a new partnership between Euler Labs and Uniswap Foundation, the teams intend to expose EulerSwap's core logic and mechanisms via a Uniswap v4 Hook interface. -This is primarily done by inheriting `EulerSwap.sol:EulerSwap`, i.e. `EulerSwapHook is EulerSwap, BaseHook`, and implementing a "custom curve" via `beforeSwap`. The implementation will allow integrators, interfaces, and aggregators, to trade on EulerSwap as-if it is any other Uniswap v4 Pool +This is primarily done by inheriting `UniswapHook.sol:UniswapHook`, i.e. `EulerSwap is UniswapHook, ...`, and implementing a "custom curve" via `beforeSwap`. The implementation will allow integrators, interfaces, and aggregators, to trade on EulerSwap as-if it is any other Uniswap v4 Pool ```solidity // assuming the EulerSwapHook was instantiated via EulerSwapFactory @@ -10,7 +10,7 @@ PoolKey memory poolKey = PoolKey({ currency0: currency0, currency1: currency1, fee: fee, - tickSpacing: 60, + tickSpacing: 1, hooks: IHooks(address(eulerSwapHook)) }); @@ -20,23 +20,30 @@ minimalRouter.swap(poolKey, zeroForOne, amountIn, 0); ## Audit Scope -The scope of audit involves the code-diff introduced by [PR #48](https://github.com/euler-xyz/euler-swap/pull/48/files). **As of Apr 1st, 2025, the diff is subject to change but will be code-complete by the audit start time.** - -Major Changes will include: - -* Replacing `binarySearch` quoting algorithm with a closed-form formula -* Implementing a protocol fee, as a percentage of LP fees, enacted by governance - -As for the files in scope, only files from `src/` should be considered: +The scope of audit involves a re-audit of EulerSwap, primarily `src/`: ``` ├── src +│ ├── CtxLib.sol +│ ├── CurveLib.sol +│ ├── EulerSwap.sol │ ├── EulerSwapFactory.sol -│ ├── EulerSwapHook.sol -│ └── utils -│ └── HookMiner.sol +│ ├── EulerSwapPeriphery.sol +│ ├── FundsLib.sol +│ ├── MetaProxyDeployer.sol +│ ├── QuoteLib.sol +│ ├── UniswapHook.sol ``` +> The interfaces are out of scope + +## Notable Changes since the prior audit: + +* Introduction of Uniswap v4 Hook logic +* Addition of a protocol fee +* Refactoring EulerSwap instances to delegate call into an implementation contract +* Replaced binary-search quoting, with a closed formula `fInverse()` + ## Known Caveats ### Prepaid Inputs From 97f1e5c3baab8a205ec92e26272f44a3af8853f4 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 16 Apr 2025 00:17:25 +0100 Subject: [PATCH 265/312] building with protocol fee owner --- src/EulerSwapFactory.sol | 12 ++++++++++-- src/utils/ProtocolFee.sol | 24 ++++++++++++++++++++++++ test/EulerSwapTestBase.t.sol | 2 +- 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 src/utils/ProtocolFee.sol diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index d6d7c09..99f7080 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -6,12 +6,13 @@ import {EVCUtil} from "ethereum-vault-connector/utils/EVCUtil.sol"; import {GenericFactory} from "evk/GenericFactory/GenericFactory.sol"; import {EulerSwap} from "./EulerSwap.sol"; +import {ProtocolFee} from "./utils/ProtocolFee.sol"; import {MetaProxyDeployer} from "./MetaProxyDeployer.sol"; /// @title EulerSwapFactory contract /// @custom:security-contact security@euler.xyz /// @author Euler Labs (https://www.eulerlabs.com/) -contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { +contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { /// @dev An array to store all pools addresses. address[] private allPools; /// @dev Vaults must be deployed by this factory @@ -33,7 +34,10 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { error InvalidVaultImplementation(); error SliceOutOfBounds(); - constructor(address evc, address evkFactory_, address eulerSwapImpl_) EVCUtil(evc) { + constructor(address evc, address evkFactory_, address eulerSwapImpl_, address feeOwner_) + EVCUtil(evc) + ProtocolFee(feeOwner_) + { evkFactory = evkFactory_; eulerSwapImpl = eulerSwapImpl_; } @@ -51,6 +55,10 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { uninstall(params.eulerAccount); + // set protocol fee + params.protocolFee = protocolFee; + params.protocolFeeRecipient = protocolFeeRecipient; + EulerSwap pool = EulerSwap( MetaProxyDeployer.deployMetaProxy( eulerSwapImpl, abi.encode(params), keccak256(abi.encode(params.eulerAccount, salt)) diff --git a/src/utils/ProtocolFee.sol b/src/utils/ProtocolFee.sol new file mode 100644 index 0000000..8f3dd03 --- /dev/null +++ b/src/utils/ProtocolFee.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.27; + +import {Owned} from "solmate/src/auth/Owned.sol"; + +abstract contract ProtocolFee is Owned { + uint256 public protocolFee; + address public protocolFeeRecipient; + + error InvalidFee(); + + constructor(address _feeOwner) Owned(_feeOwner) {} + + /// @notice Set the protocol fee, expressed as a percentage of LP fee + /// @param newFee The new protocol fee, in WAD units (0.10e18 = 10%) + function setProtocolFee(uint256 newFee) external onlyOwner { + require(newFee < 1e18, InvalidFee()); + protocolFee = newFee; + } + + function setProtocolFeeRecipient(address newRecipient) external onlyOwner { + protocolFeeRecipient = newRecipient; + } +} diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index 1e6ebc0..08d7e24 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -38,7 +38,7 @@ contract EulerSwapTestBase is EVaultTestBase { function deployEulerSwap(address poolManager_) public { eulerSwapImpl = address(new EulerSwap(address(evc), poolManager_)); - eulerSwapFactory = new EulerSwapFactory(address(evc), address(factory), eulerSwapImpl); + eulerSwapFactory = new EulerSwapFactory(address(evc), address(factory), eulerSwapImpl, address(this)); periphery = new EulerSwapPeriphery(); } From f8bedf80c91ef1a06c936f1ca56bbbdd2b0e9a4b Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 16 Apr 2025 00:29:36 +0100 Subject: [PATCH 266/312] wip testing --- test/HookFees.t.sol | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/test/HookFees.t.sol b/test/HookFees.t.sol index 6989143..d52644f 100644 --- a/test/HookFees.t.sol +++ b/test/HookFees.t.sol @@ -17,6 +17,8 @@ import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; contract HookFeesTest is EulerSwapTestBase { using StateLibrary for IPoolManager; + address protocolFeeRecipient = makeAddr("protocolFeeRecipient"); + EulerSwap public eulerSwap; IPoolManager public poolManager; @@ -120,4 +122,53 @@ contract HookFeesTest is EulerSwapTestBase { assertGt(getHolderNAV(), origNav + int256(amountIn - amountInWithoutFee)); } + + function test_protocolFee() public { + IEulerSwap.Params memory params = eulerSwap.getParams(); + vm.prank(params.eulerAccount); + eulerSwapFactory.uninstallPool(); + + // set protocol fee to 10% of the LP fee + eulerSwapFactory.setProtocolFee(0.1e18); + eulerSwapFactory.setProtocolFeeRecipient(protocolFeeRecipient); + + // set swap fee to 10 bips and activate the pool + eulerSwap = createEulerSwapHook(60e18, 60e18, 0.001e18, 1e18, 1e18, 0.4e18, 0.85e18); + + int256 origNav = getHolderNAV(); + (uint112 r0, uint112 r1,) = eulerSwap.getReserves(); + + uint256 amountIn = 1e18; + uint256 amountInWithoutFee = amountIn - (amountIn * eulerSwap.getParams().fee / 1e18); + uint256 amountOut = + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), amountIn); + + assetTST.mint(anyone, amountIn); + + vm.startPrank(anyone); + assetTST.approve(address(minimalRouter), amountIn); + + bool zeroForOne = address(assetTST) < address(assetTST2); + BalanceDelta result = minimalRouter.swap(eulerSwap.poolKey(), zeroForOne, amountIn, 0, ""); + vm.stopPrank(); + + assertEq(assetTST.balanceOf(anyone), 0); + assertEq(assetTST2.balanceOf(anyone), amountOut); + + assertEq(zeroForOne ? uint256(-int256(result.amount0())) : uint256(-int256(result.amount1())), amountIn); + assertEq(zeroForOne ? uint256(int256(result.amount1())) : uint256(int256(result.amount0())), amountOut); + + // assert fees were not added to the reserves + (uint112 r0New, uint112 r1New,) = eulerSwap.getReserves(); + if (zeroForOne) { + assertEq(r0New, r0 + amountInWithoutFee); + assertEq(r1New, r1 - amountOut); + } else { + // oneForZero, so the curve received asset1 + assertEq(r0New, r0 - amountOut); + assertEq(r1New, r1 + amountInWithoutFee); + } + + assertGt(getHolderNAV(), origNav + int256(amountIn - amountInWithoutFee)); + } } From 01c759dab3385dd65525b8a3b4322e947128389f Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 16 Apr 2025 00:33:18 +0100 Subject: [PATCH 267/312] assertions for protocol fee --- test/HookFees.t.sol | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/HookFees.t.sol b/test/HookFees.t.sol index d52644f..f4ecd22 100644 --- a/test/HookFees.t.sol +++ b/test/HookFees.t.sol @@ -169,6 +169,9 @@ contract HookFeesTest is EulerSwapTestBase { assertEq(r1New, r1 + amountInWithoutFee); } - assertGt(getHolderNAV(), origNav + int256(amountIn - amountInWithoutFee)); + uint256 protocolFeeCollected = assetTST.balanceOf(protocolFeeRecipient); + assertGt(protocolFeeCollected, 0); + + assertGt(getHolderNAV(), origNav + int256(amountIn - amountInWithoutFee) - int256(protocolFeeCollected)); } } From 9adb695033b4aa8777d39275b9ad512051c6bfca Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 15 Apr 2025 19:43:15 -0400 Subject: [PATCH 268/312] ensure quotes for 0 amount swaps return exactly 0 --- src/QuoteLib.sol | 2 ++ test/Periphery.t.sol | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/QuoteLib.sol b/src/QuoteLib.sol index 9213eca..7506a90 100644 --- a/src/QuoteLib.sol +++ b/src/QuoteLib.sol @@ -29,6 +29,8 @@ library QuoteLib { view returns (uint256) { + if (amount == 0) return 0; + require(IEVC(evc).isAccountOperatorAuthorized(p.eulerAccount, address(this)), OperatorNotInstalled()); require(amount <= type(uint112).max, SwapLimitExceeded()); diff --git a/test/Periphery.t.sol b/test/Periphery.t.sol index 46a14a2..75fa610 100644 --- a/test/Periphery.t.sol +++ b/test/Periphery.t.sol @@ -120,4 +120,12 @@ contract PeripheryTest is EulerSwapTestBase { assertEq(assetTST2.balanceOf(anyone), amountOut); } + + function test_SwapZeroAmounts() public view { + assertEq(periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(assetTST2), 0), 0); + assertEq(periphery.quoteExactInput(address(eulerSwap), address(assetTST2), address(assetTST), 0), 0); + + assertEq(periphery.quoteExactOutput(address(eulerSwap), address(assetTST), address(assetTST2), 0), 0); + assertEq(periphery.quoteExactOutput(address(eulerSwap), address(assetTST2), address(assetTST), 0), 0); + } } From 78291703ac8b50c07c6574cb07f4c9c456ed87d5 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 15 Apr 2025 20:30:19 -0400 Subject: [PATCH 269/312] finish test harness for protocol fee params --- test/Ctx.t.sol | 2 +- test/EulerSwapTestBase.t.sol | 40 +++++++++++++++++++++++++++++++----- test/FactoryTest.t.sol | 2 +- test/HookFees.t.sol | 10 ++++----- 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/test/Ctx.t.sol b/test/Ctx.t.sol index 76bfd1b..8ee8e27 100644 --- a/test/Ctx.t.sol +++ b/test/Ctx.t.sol @@ -14,7 +14,7 @@ contract CtxTest is EulerSwapTestBase { } function test_staticParamSize() public view { - IEulerSwap.Params memory params = getEulerSwapParams(1e18, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 0); + IEulerSwap.Params memory params = getEulerSwapParams(1e18, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 0, 0, address(0)); assertEq(abi.encode(params).length, 384); } } diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index 08d7e24..a1d6ac5 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -129,10 +129,24 @@ contract EulerSwapTestBase is EVaultTestBase { uint256 py, uint256 cx, uint256 cy + ) internal returns (EulerSwap) { + return createEulerSwapFull(reserve0, reserve1, fee, px, py, cx, cy, 0, address(0)); + } + + function createEulerSwapFull( + uint112 reserve0, + uint112 reserve1, + uint256 fee, + uint256 px, + uint256 py, + uint256 cx, + uint256 cy, + uint256 protocolFee, + address protcoolFeeRecipient ) internal returns (EulerSwap) { removeInstalledOperator(); - IEulerSwap.Params memory params = getEulerSwapParams(reserve0, reserve1, px, py, cx, cy, fee); + IEulerSwap.Params memory params = getEulerSwapParams(reserve0, reserve1, px, py, cx, cy, fee, protocolFee, protcoolFeeRecipient); IEulerSwap.InitialState memory initialState = IEulerSwap.InitialState({currReserve0: reserve0, currReserve1: reserve1}); @@ -158,10 +172,24 @@ contract EulerSwapTestBase is EVaultTestBase { uint256 py, uint256 cx, uint256 cy + ) internal returns (EulerSwap) { + return createEulerSwapHookFull(reserve0, reserve1, fee, px, py, cx, cy, 0, address(0)); + } + + function createEulerSwapHookFull( + uint112 reserve0, + uint112 reserve1, + uint256 fee, + uint256 px, + uint256 py, + uint256 cx, + uint256 cy, + uint256 protocolFee, + address protocolFeeRecipient ) internal returns (EulerSwap) { removeInstalledOperator(); - IEulerSwap.Params memory params = getEulerSwapParams(reserve0, reserve1, px, py, cx, cy, fee); + IEulerSwap.Params memory params = getEulerSwapParams(reserve0, reserve1, px, py, cx, cy, fee, protocolFee, protocolFeeRecipient); IEulerSwap.InitialState memory initialState = IEulerSwap.InitialState({currReserve0: reserve0, currReserve1: reserve1}); @@ -235,7 +263,9 @@ contract EulerSwapTestBase is EVaultTestBase { uint256 py, uint256 cx, uint256 cy, - uint256 fee + uint256 fee, + uint256 protocolFee, + address protocolFeeRecipient ) internal view returns (EulerSwap.Params memory) { return IEulerSwap.Params({ vault0: address(eTST), @@ -248,8 +278,8 @@ contract EulerSwapTestBase is EVaultTestBase { concentrationX: cx, concentrationY: cy, fee: fee, - protocolFee: 0, - protocolFeeRecipient: address(0) + protocolFee: protocolFee, + protocolFeeRecipient: protocolFeeRecipient }); } diff --git a/test/FactoryTest.t.sol b/test/FactoryTest.t.sol index efb8242..a83ec7b 100644 --- a/test/FactoryTest.t.sol +++ b/test/FactoryTest.t.sol @@ -28,7 +28,7 @@ contract FactoryTest is EulerSwapTestBase { view returns (IEulerSwap.Params memory poolParams, IEulerSwap.InitialState memory initialState) { - poolParams = getEulerSwapParams(1e18, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 0); + poolParams = getEulerSwapParams(1e18, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 0, 0, address(0)); initialState = IEulerSwap.InitialState({currReserve0: 1e18, currReserve1: 1e18}); } diff --git a/test/HookFees.t.sol b/test/HookFees.t.sol index f4ecd22..65f15b9 100644 --- a/test/HookFees.t.sol +++ b/test/HookFees.t.sol @@ -124,16 +124,14 @@ contract HookFeesTest is EulerSwapTestBase { } function test_protocolFee() public { - IEulerSwap.Params memory params = eulerSwap.getParams(); - vm.prank(params.eulerAccount); - eulerSwapFactory.uninstallPool(); - // set protocol fee to 10% of the LP fee - eulerSwapFactory.setProtocolFee(0.1e18); + uint256 protocolFee = 0.1e18; + + eulerSwapFactory.setProtocolFee(protocolFee); eulerSwapFactory.setProtocolFeeRecipient(protocolFeeRecipient); // set swap fee to 10 bips and activate the pool - eulerSwap = createEulerSwapHook(60e18, 60e18, 0.001e18, 1e18, 1e18, 0.4e18, 0.85e18); + eulerSwap = createEulerSwapHookFull(60e18, 60e18, 0.001e18, 1e18, 1e18, 0.4e18, 0.85e18, protocolFee, protocolFeeRecipient); int256 origNav = getHolderNAV(); (uint112 r0, uint112 r1,) = eulerSwap.getReserves(); From 519aced0341073f0d3824c454f1610413c69a9e9 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 15 Apr 2025 20:32:35 -0400 Subject: [PATCH 270/312] forge fmt --- test/EulerSwapTestBase.t.sol | 6 ++++-- test/HookFees.t.sol | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index a1d6ac5..af7ff34 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -146,7 +146,8 @@ contract EulerSwapTestBase is EVaultTestBase { ) internal returns (EulerSwap) { removeInstalledOperator(); - IEulerSwap.Params memory params = getEulerSwapParams(reserve0, reserve1, px, py, cx, cy, fee, protocolFee, protcoolFeeRecipient); + IEulerSwap.Params memory params = + getEulerSwapParams(reserve0, reserve1, px, py, cx, cy, fee, protocolFee, protcoolFeeRecipient); IEulerSwap.InitialState memory initialState = IEulerSwap.InitialState({currReserve0: reserve0, currReserve1: reserve1}); @@ -189,7 +190,8 @@ contract EulerSwapTestBase is EVaultTestBase { ) internal returns (EulerSwap) { removeInstalledOperator(); - IEulerSwap.Params memory params = getEulerSwapParams(reserve0, reserve1, px, py, cx, cy, fee, protocolFee, protocolFeeRecipient); + IEulerSwap.Params memory params = + getEulerSwapParams(reserve0, reserve1, px, py, cx, cy, fee, protocolFee, protocolFeeRecipient); IEulerSwap.InitialState memory initialState = IEulerSwap.InitialState({currReserve0: reserve0, currReserve1: reserve1}); diff --git a/test/HookFees.t.sol b/test/HookFees.t.sol index 65f15b9..e8aa47f 100644 --- a/test/HookFees.t.sol +++ b/test/HookFees.t.sol @@ -131,7 +131,9 @@ contract HookFeesTest is EulerSwapTestBase { eulerSwapFactory.setProtocolFeeRecipient(protocolFeeRecipient); // set swap fee to 10 bips and activate the pool - eulerSwap = createEulerSwapHookFull(60e18, 60e18, 0.001e18, 1e18, 1e18, 0.4e18, 0.85e18, protocolFee, protocolFeeRecipient); + eulerSwap = createEulerSwapHookFull( + 60e18, 60e18, 0.001e18, 1e18, 1e18, 0.4e18, 0.85e18, protocolFee, protocolFeeRecipient + ); int256 origNav = getHolderNAV(); (uint112 r0, uint112 r1,) = eulerSwap.getReserves(); From 4334265440bd7ebc2751bde530c052baa6807f7b Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 16 Apr 2025 19:14:20 +0100 Subject: [PATCH 271/312] note invalidated salt --- docs/audits/EulerSwapHook_Audit_Scope.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/audits/EulerSwapHook_Audit_Scope.md b/docs/audits/EulerSwapHook_Audit_Scope.md index 2f6b08f..adbc546 100644 --- a/docs/audits/EulerSwapHook_Audit_Scope.md +++ b/docs/audits/EulerSwapHook_Audit_Scope.md @@ -50,4 +50,12 @@ The scope of audit involves a re-audit of EulerSwap, primarily `src/`: Due to technical requirements, EulerSwapHook must take the input token from PoolManager and deposit it into Euler Vaults. It will appear that EulerSwapHook can only support input sizes of `IERC20.balanceOf(PoolManager)`. However swap routers can pre-emptively send input tokens (from user wallet to PoolManager) prior to calling `poolManager.swap` to get around this limitation. -An example `test/utils/MinimalRouter.sol` is provided as an example. \ No newline at end of file +An example `test/utils/MinimalRouter.sol` is provided as an example. + +### Invalidated Salts + +Uniswap v4 Hooks encode their behaviors within the address, requiring deployers to mine salts for a particular address pattern. Because constructor arguments influence the precomputed address during the salt-finding process, governance may accidentally invalidate a discovered salt by updating the protocol fee. + +The EulerSwapFactory passes a protocol fee and protocol fee recipient to a EulerSwap instance (hook). If governance were modify either values between salt-discovery and EulerSwap deployment, the deployment would fail. + +This scenario is unlikely to happen as we do not expect protocol fee parameters to change; as well, governance can pre-emptively warn deployers of the parameter change. From 7cc4f9441f948bf764e38e5c295955c171ade7f6 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 16 Apr 2025 18:53:21 -0400 Subject: [PATCH 272/312] typo --- test/EulerSwapTestBase.t.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index 2fbcd77..2c131b0 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -151,12 +151,12 @@ contract EulerSwapTestBase is EVaultTestBase { uint256 cx, uint256 cy, uint256 protocolFee, - address protcoolFeeRecipient + address protocolFeeRecipient ) internal returns (EulerSwap) { removeInstalledOperator(); IEulerSwap.Params memory params = - getEulerSwapParams(reserve0, reserve1, px, py, cx, cy, fee, protocolFee, protcoolFeeRecipient); + getEulerSwapParams(reserve0, reserve1, px, py, cx, cy, fee, protocolFee, protocolFeeRecipient); IEulerSwap.InitialState memory initialState = IEulerSwap.InitialState({currReserve0: reserve0, currReserve1: reserve1}); From 1a714a41a76324b8300ca57733df853b80d97c07 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 16 Apr 2025 18:58:39 -0400 Subject: [PATCH 273/312] re-org --- src/EulerSwap.sol | 8 ++++---- src/EulerSwapFactory.sol | 2 +- src/UniswapHook.sol | 8 ++++---- src/{ => libraries}/CtxLib.sol | 2 +- src/{ => libraries}/CurveLib.sol | 2 +- src/{ => libraries}/FundsLib.sol | 2 +- src/{ => libraries}/QuoteLib.sol | 2 +- src/{ => utils}/MetaProxyDeployer.sol | 0 test/Ctx.t.sol | 2 +- test/DepositFailures.t.sol | 2 +- test/EulerSwapTestBase.t.sol | 2 +- test/FactoryTest.t.sol | 2 +- test/Fees.t.sol | 2 +- test/Limits.t.sol | 2 +- 14 files changed, 19 insertions(+), 19 deletions(-) rename src/{ => libraries}/CtxLib.sol (95%) rename src/{ => libraries}/CurveLib.sol (98%) rename src/{ => libraries}/FundsLib.sol (98%) rename src/{ => libraries}/QuoteLib.sol (99%) rename src/{ => utils}/MetaProxyDeployer.sol (100%) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 705dd41..8d0a857 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -9,10 +9,10 @@ import {IEVault} from "evk/EVault/IEVault.sol"; import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; import {UniswapHook} from "./UniswapHook.sol"; -import {CtxLib} from "./CtxLib.sol"; -import {FundsLib} from "./FundsLib.sol"; -import {CurveLib} from "./CurveLib.sol"; -import {QuoteLib} from "./QuoteLib.sol"; +import {CtxLib} from "./libraries/CtxLib.sol"; +import {FundsLib} from "./libraries/FundsLib.sol"; +import {CurveLib} from "./libraries/CurveLib.sol"; +import {QuoteLib} from "./libraries/QuoteLib.sol"; contract EulerSwap is IEulerSwap, EVCUtil, UniswapHook { bytes32 public constant curve = bytes32("EulerSwap v1"); diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 99f7080..6eb2427 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -7,7 +7,7 @@ import {GenericFactory} from "evk/GenericFactory/GenericFactory.sol"; import {EulerSwap} from "./EulerSwap.sol"; import {ProtocolFee} from "./utils/ProtocolFee.sol"; -import {MetaProxyDeployer} from "./MetaProxyDeployer.sol"; +import {MetaProxyDeployer} from "./utils/MetaProxyDeployer.sol"; /// @title EulerSwapFactory contract /// @custom:security-contact security@euler.xyz diff --git a/src/UniswapHook.sol b/src/UniswapHook.sol index 45f94de..d60846f 100644 --- a/src/UniswapHook.sol +++ b/src/UniswapHook.sol @@ -15,10 +15,10 @@ import { import {IEVault} from "evk/EVault/IEVault.sol"; import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; -import {CtxLib} from "./CtxLib.sol"; -import {QuoteLib} from "./QuoteLib.sol"; -import {CurveLib} from "./CurveLib.sol"; -import {FundsLib} from "./FundsLib.sol"; +import {CtxLib} from "./libraries/CtxLib.sol"; +import {QuoteLib} from "./libraries/QuoteLib.sol"; +import {CurveLib} from "./libraries/CurveLib.sol"; +import {FundsLib} from "./libraries/FundsLib.sol"; contract UniswapHook is BaseHook { using SafeCast for uint256; diff --git a/src/CtxLib.sol b/src/libraries/CtxLib.sol similarity index 95% rename from src/CtxLib.sol rename to src/libraries/CtxLib.sol index 6486461..8649a3d 100644 --- a/src/CtxLib.sol +++ b/src/libraries/CtxLib.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; -import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; +import {IEulerSwap} from "../interfaces/IEulerSwap.sol"; library CtxLib { struct Storage { diff --git a/src/CurveLib.sol b/src/libraries/CurveLib.sol similarity index 98% rename from src/CurveLib.sol rename to src/libraries/CurveLib.sol index d3c1062..8c46025 100644 --- a/src/CurveLib.sol +++ b/src/libraries/CurveLib.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.27; import {Math} from "openzeppelin-contracts/utils/math/Math.sol"; -import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; +import {IEulerSwap} from "../interfaces/IEulerSwap.sol"; library CurveLib { error Overflow(); diff --git a/src/FundsLib.sol b/src/libraries/FundsLib.sol similarity index 98% rename from src/FundsLib.sol rename to src/libraries/FundsLib.sol index 297e8d6..8241501 100644 --- a/src/FundsLib.sol +++ b/src/libraries/FundsLib.sol @@ -8,7 +8,7 @@ import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault, IBorrowing, IERC4626, IRiskManager} from "evk/EVault/IEVault.sol"; import {Errors as EVKErrors} from "evk/EVault/shared/Errors.sol"; -import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; +import {IEulerSwap} from "../interfaces/IEulerSwap.sol"; library FundsLib { using SafeERC20 for IERC20; diff --git a/src/QuoteLib.sol b/src/libraries/QuoteLib.sol similarity index 99% rename from src/QuoteLib.sol rename to src/libraries/QuoteLib.sol index 7506a90..6be7779 100644 --- a/src/QuoteLib.sol +++ b/src/libraries/QuoteLib.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.27; import {IEVC} from "evc/interfaces/IEthereumVaultConnector.sol"; import {IEVault} from "evk/EVault/IEVault.sol"; -import {IEulerSwap} from "./interfaces/IEulerSwap.sol"; +import {IEulerSwap} from "../interfaces/IEulerSwap.sol"; import {CtxLib} from "./CtxLib.sol"; import {CurveLib} from "./CurveLib.sol"; diff --git a/src/MetaProxyDeployer.sol b/src/utils/MetaProxyDeployer.sol similarity index 100% rename from src/MetaProxyDeployer.sol rename to src/utils/MetaProxyDeployer.sol diff --git a/test/Ctx.t.sol b/test/Ctx.t.sol index 8ee8e27..5f2d87d 100644 --- a/test/Ctx.t.sol +++ b/test/Ctx.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.24; import {EulerSwapTestBase, IEulerSwap} from "./EulerSwapTestBase.t.sol"; -import {CtxLib} from "../src/CtxLib.sol"; +import {CtxLib} from "../src/libraries/CtxLib.sol"; contract CtxTest is EulerSwapTestBase { function setUp() public virtual override { diff --git a/test/DepositFailures.t.sol b/test/DepositFailures.t.sol index c962c51..5cee89f 100644 --- a/test/DepositFailures.t.sol +++ b/test/DepositFailures.t.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.24; import {IEVault, IEulerSwap, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; import {IRMTestFixed} from "evk-test/mocks/IRMTestFixed.sol"; import {Errors as EVKErrors} from "evk/EVault/shared/Errors.sol"; -import {FundsLib} from "../src/FundsLib.sol"; +import {FundsLib} from "../src/libraries/FundsLib.sol"; import "evk/EVault/shared/Constants.sol" as EVKConstants; contract DepositFailuresTest is EulerSwapTestBase { diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index 2c131b0..7fc4005 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -11,7 +11,7 @@ import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {HookMiner} from "./utils/HookMiner.sol"; import {HookMiner as v4HookMiner} from "v4-periphery/src/utils/HookMiner.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; -import {MetaProxyDeployer} from "../src/MetaProxyDeployer.sol"; +import {MetaProxyDeployer} from "../src/utils/MetaProxyDeployer.sol"; contract EulerSwapTestBase is EVaultTestBase { uint256 public constant MAX_QUOTE_ERROR = 4; diff --git a/test/FactoryTest.t.sol b/test/FactoryTest.t.sol index 6956b10..d8bd4d2 100644 --- a/test/FactoryTest.t.sol +++ b/test/FactoryTest.t.sol @@ -8,7 +8,7 @@ import {HookMiner} from "./utils/HookMiner.sol"; import {EulerSwapTestBase, IEulerSwap, IEVC, EulerSwap} from "./EulerSwapTestBase.t.sol"; import {EulerSwapFactory, IEulerSwapFactory} from "../src/EulerSwapFactory.sol"; import {EulerSwap} from "../src/EulerSwap.sol"; -import {MetaProxyDeployer} from "../src/MetaProxyDeployer.sol"; +import {MetaProxyDeployer} from "../src/utils/MetaProxyDeployer.sol"; contract FactoryTest is EulerSwapTestBase { IPoolManager public poolManager; diff --git a/test/Fees.t.sol b/test/Fees.t.sol index 635b049..61ee202 100644 --- a/test/Fees.t.sol +++ b/test/Fees.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.24; import {Test, console} from "forge-std/Test.sol"; import {IEVault, IEulerSwap, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; -import {CurveLib} from "../src/CurveLib.sol"; +import {CurveLib} from "../src/libraries/CurveLib.sol"; contract FeesTest is EulerSwapTestBase { EulerSwap public eulerSwap; diff --git a/test/Limits.t.sol b/test/Limits.t.sol index e6e3c47..2cef14e 100644 --- a/test/Limits.t.sol +++ b/test/Limits.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.24; import {EulerSwapTestBase, EulerSwap, EulerSwapPeriphery, IEulerSwap} from "./EulerSwapTestBase.t.sol"; -import {QuoteLib} from "../src/QuoteLib.sol"; +import {QuoteLib} from "../src/libraries/QuoteLib.sol"; contract LimitsTest is EulerSwapTestBase { EulerSwap public eulerSwap; From 2830d60c9d994778f94e5ba19ab9061e1520b942 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Thu, 17 Apr 2025 18:25:05 +0100 Subject: [PATCH 274/312] revert on subsequent initalize --- src/UniswapHook.sol | 12 +++++++++++- test/EulerSwapTestBase.t.sol | 10 ++++++++-- test/FactoryTest.t.sol | 6 ++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/UniswapHook.sol b/src/UniswapHook.sol index d60846f..7d051b6 100644 --- a/src/UniswapHook.sol +++ b/src/UniswapHook.sol @@ -27,6 +27,7 @@ contract UniswapHook is BaseHook { PoolKey internal _poolKey; + error AlreadyInitialized(); error NativeConcentratedLiquidityUnsupported(); constructor(address evc_, address _poolManager) BaseHook(IPoolManager(_poolManager)) { @@ -118,6 +119,15 @@ contract UniswapHook is BaseHook { return (BaseHook.beforeSwap.selector, returnDelta, 0); } + /// @dev Each deployed hook only services one pair and prevent subsequent initializations + function _beforeInitialize(address, PoolKey calldata, uint160) internal view override returns (bytes4) { + // when the hook is deployed for the first time, the internal _poolKey is empty + // upon activation, the internal _poolKey is initialized and set + // once the hook contract is activated, do not allow subsequent initializations + require(_poolKey.tickSpacing == 0, AlreadyInitialized()); + return BaseHook.beforeInitialize.selector; + } + function _beforeAddLiquidity(address, PoolKey calldata, IPoolManager.ModifyLiquidityParams calldata, bytes calldata) internal pure @@ -129,7 +139,7 @@ contract UniswapHook is BaseHook { function getHookPermissions() public pure override returns (Hooks.Permissions memory) { return Hooks.Permissions({ - beforeInitialize: false, + beforeInitialize: true, afterInitialize: false, beforeAddLiquidity: true, afterAddLiquidity: false, diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index 7fc4005..9eb887a 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -41,7 +41,10 @@ contract EulerSwapTestBase is EVaultTestBase { // use the canonical miner to find a valid 'implementation' address (, bytes32 salt) = v4HookMiner.find( address(this), - uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG), + uint160( + Hooks.BEFORE_INITIALIZE_FLAG | Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG + | Hooks.BEFORE_ADD_LIQUIDITY_FLAG + ), type(EulerSwap).creationCode, abi.encode(address(evc), poolManager_) ); @@ -208,7 +211,10 @@ contract EulerSwapTestBase is EVaultTestBase { (address predictedAddr, bytes32 salt) = HookMiner.find( address(eulerSwapFactory), holder, - uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG), + uint160( + Hooks.BEFORE_INITIALIZE_FLAG | Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG + | Hooks.BEFORE_ADD_LIQUIDITY_FLAG + ), creationCode ); diff --git a/test/FactoryTest.t.sol b/test/FactoryTest.t.sol index d8bd4d2..036845f 100644 --- a/test/FactoryTest.t.sol +++ b/test/FactoryTest.t.sol @@ -33,8 +33,10 @@ contract FactoryTest is EulerSwapTestBase { } function mineSalt(IEulerSwap.Params memory poolParams) internal view returns (address hookAddress, bytes32 salt) { - uint160 flags = - uint160(Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG); + uint160 flags = uint160( + Hooks.BEFORE_INITIALIZE_FLAG | Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG + | Hooks.BEFORE_ADD_LIQUIDITY_FLAG + ); bytes memory creationCode = MetaProxyDeployer.creationCodeMetaProxy(eulerSwapImpl, abi.encode(poolParams)); (hookAddress, salt) = HookMiner.find(address(eulerSwapFactory), holder, flags, creationCode); } From c99a5d689ff55cfaf8088c51cb88b0320ab2da61 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Thu, 17 Apr 2025 18:30:28 +0100 Subject: [PATCH 275/312] test revert second initialize --- test/HookSwaps.t.sol | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/HookSwaps.t.sol b/test/HookSwaps.t.sol index fc0824e..be69a1e 100644 --- a/test/HookSwaps.t.sol +++ b/test/HookSwaps.t.sol @@ -155,6 +155,25 @@ contract HookSwapsTest is EulerSwapTestBase { vm.stopPrank(); } + /// @dev initializing a new pool on an existing eulerswap instance will revert + function test_revertSubsequentInitialize() public { + PoolKey memory poolKey = eulerSwap.poolKey(); + PoolKey memory newPoolKey = eulerSwap.poolKey(); + newPoolKey.currency0 = CurrencyLibrary.ADDRESS_ZERO; + + // hook intentionally reverts to prevent subsequent initializations + vm.expectRevert( + abi.encodeWithSelector( + CustomRevert.WrappedError.selector, + address(eulerSwap), + IHooks.beforeInitialize.selector, + abi.encodeWithSelector(UniswapHook.AlreadyInitialized.selector), + abi.encodeWithSelector(Hooks.HookCallFailed.selector) + ) + ); + poolManager.initialize(newPoolKey, 79228162514264337593543950336); + } + function _swap(PoolKey memory key, bool zeroForOne, bool exactInput, uint256 amount) internal { IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ zeroForOne: zeroForOne, From 794934588073db9d3bb4ffb526b39155bcddb356 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 18 Apr 2025 12:05:53 -0400 Subject: [PATCH 276/312] remove unused variable --- test/HookSwaps.t.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/test/HookSwaps.t.sol b/test/HookSwaps.t.sol index be69a1e..0eac841 100644 --- a/test/HookSwaps.t.sol +++ b/test/HookSwaps.t.sol @@ -157,7 +157,6 @@ contract HookSwapsTest is EulerSwapTestBase { /// @dev initializing a new pool on an existing eulerswap instance will revert function test_revertSubsequentInitialize() public { - PoolKey memory poolKey = eulerSwap.poolKey(); PoolKey memory newPoolKey = eulerSwap.poolKey(); newPoolKey.currency0 = CurrencyLibrary.ADDRESS_ZERO; From ddf36144cf38f374cd069806a50c09c1f06c3d84 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Thu, 17 Apr 2025 14:28:50 -0400 Subject: [PATCH 277/312] improve error message when protocol fee is invalid --- src/EulerSwapFactory.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 6eb2427..c115ec0 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -33,6 +33,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { error OperatorNotInstalled(); error InvalidVaultImplementation(); error SliceOutOfBounds(); + error InvalidProtocolFee(); constructor(address evc, address evkFactory_, address eulerSwapImpl_, address feeOwner_) EVCUtil(evc) @@ -52,13 +53,13 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { GenericFactory(evkFactory).isProxy(params.vault0) && GenericFactory(evkFactory).isProxy(params.vault1), InvalidVaultImplementation() ); + require( + params.protocolFee == protocolFee && params.protocolFeeRecipient == protocolFeeRecipient, + InvalidProtocolFee() + ); uninstall(params.eulerAccount); - // set protocol fee - params.protocolFee = protocolFee; - params.protocolFeeRecipient = protocolFeeRecipient; - EulerSwap pool = EulerSwap( MetaProxyDeployer.deployMetaProxy( eulerSwapImpl, abi.encode(params), keccak256(abi.encode(params.eulerAccount, salt)) From 63a789628c34660c12f6b1cd7425c89bece8d7f5 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 18 Apr 2025 12:07:44 -0400 Subject: [PATCH 278/312] test poolManager accessor --- test/FactoryTest.t.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/FactoryTest.t.sol b/test/FactoryTest.t.sol index 036845f..b925d27 100644 --- a/test/FactoryTest.t.sol +++ b/test/FactoryTest.t.sol @@ -88,6 +88,8 @@ contract FactoryTest is EulerSwapTestBase { address eulerSwap = eulerSwapFactory.poolByEulerAccount(holder); + assertEq(address(EulerSwap(eulerSwap).poolManager()), address(poolManager)); + uint256 allPoolsLengthAfter = eulerSwapFactory.poolsLength(); assertEq(allPoolsLengthAfter - allPoolsLengthBefore, 1); From eebc566e4f476c4878f7200c656db68ad6b798f3 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 18 Apr 2025 14:40:40 -0400 Subject: [PATCH 279/312] validate proxy addrs are valid hooks, don't bother with the implementation's addr --- src/UniswapHook.sol | 7 +++++++ test/EulerSwapTestBase.t.sol | 14 +------------- test/FactoryTest.t.sol | 24 ++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/UniswapHook.sol b/src/UniswapHook.sol index 7d051b6..f5ab544 100644 --- a/src/UniswapHook.sol +++ b/src/UniswapHook.sol @@ -35,6 +35,8 @@ contract UniswapHook is BaseHook { } function activateHook(IEulerSwap.Params memory p) internal { + Hooks.validateHookPermissions(this, getHookPermissions()); + address asset0Addr = IEVault(p.vault0).asset(); address asset1Addr = IEVault(p.vault1).asset(); @@ -58,6 +60,11 @@ contract UniswapHook is BaseHook { return _poolKey; } + /// @dev Prevent hook address validation in constructor, which is not needed + /// because hook instances are proxies. Instead, the address is validated + /// in activateHook(). + function validateHookAddress(BaseHook _this) internal pure override {} + function _beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata) internal override diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index 9eb887a..f8ec663 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -9,7 +9,6 @@ import {EulerSwapFactory} from "../src/EulerSwapFactory.sol"; import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {HookMiner} from "./utils/HookMiner.sol"; -import {HookMiner as v4HookMiner} from "v4-periphery/src/utils/HookMiner.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; import {MetaProxyDeployer} from "../src/utils/MetaProxyDeployer.sol"; @@ -38,18 +37,7 @@ contract EulerSwapTestBase is EVaultTestBase { } function deployEulerSwap(address poolManager_) public { - // use the canonical miner to find a valid 'implementation' address - (, bytes32 salt) = v4HookMiner.find( - address(this), - uint160( - Hooks.BEFORE_INITIALIZE_FLAG | Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG - | Hooks.BEFORE_ADD_LIQUIDITY_FLAG - ), - type(EulerSwap).creationCode, - abi.encode(address(evc), poolManager_) - ); - - eulerSwapImpl = address(new EulerSwap{salt: salt}(address(evc), poolManager_)); + eulerSwapImpl = address(new EulerSwap(address(evc), poolManager_)); eulerSwapFactory = new EulerSwapFactory(address(evc), address(factory), eulerSwapImpl, address(this)); periphery = new EulerSwapPeriphery(); } diff --git a/test/FactoryTest.t.sol b/test/FactoryTest.t.sol index b925d27..628cd8c 100644 --- a/test/FactoryTest.t.sol +++ b/test/FactoryTest.t.sol @@ -41,6 +41,18 @@ contract FactoryTest is EulerSwapTestBase { (hookAddress, salt) = HookMiner.find(address(eulerSwapFactory), holder, flags, creationCode); } + function mineBadSalt(IEulerSwap.Params memory poolParams) + internal + view + returns (address hookAddress, bytes32 salt) + { + // missing BEFORE_ADD_LIQUIDITY_FLAG + uint160 flags = + uint160(Hooks.BEFORE_INITIALIZE_FLAG | Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG); + bytes memory creationCode = MetaProxyDeployer.creationCodeMetaProxy(eulerSwapImpl, abi.encode(poolParams)); + (hookAddress, salt) = HookMiner.find(address(eulerSwapFactory), holder, flags, creationCode); + } + function testDeployPool() public { uint256 allPoolsLengthBefore = eulerSwapFactory.poolsLength(); @@ -117,6 +129,18 @@ contract FactoryTest is EulerSwapTestBase { evc.batch(items); } + function testBadSalt() public { + (IEulerSwap.Params memory poolParams, IEulerSwap.InitialState memory initialState) = getBasicParams(); + (address hookAddress, bytes32 salt) = mineBadSalt(poolParams); + + vm.prank(holder); + evc.setAccountOperator(holder, hookAddress, true); + + vm.expectRevert(abi.encodeWithSelector(Hooks.HookAddressNotValid.selector, hookAddress)); + vm.prank(holder); + eulerSwapFactory.deployPool(poolParams, initialState, salt); + } + function testInvalidPoolsSliceOutOfBounds() public { vm.expectRevert(EulerSwapFactory.SliceOutOfBounds.selector); eulerSwapFactory.poolsSlice(1, 0); From c6241368554dab9eeaa1d8dd048db7041d166ff0 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 20 Apr 2025 14:35:11 +0100 Subject: [PATCH 280/312] add CurveLib test --- test/CurveLib.t.sol | 59 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 test/CurveLib.t.sol diff --git a/test/CurveLib.t.sol b/test/CurveLib.t.sol new file mode 100644 index 0000000..0fa94be --- /dev/null +++ b/test/CurveLib.t.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import {EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; +import {CurveLib} from "../src/CurveLib.sol"; + +contract CurveLibTest is EulerSwapTestBase { + EulerSwap public eulerSwap; + + function setUp() public virtual override { + super.setUp(); + } + + function test_fuzzfInverse(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) + public + pure + { + + // Params + px = 1e18; + py = bound(py, 1, 1e36); + x0 = bound(x0, 1e2, 1e28); + y0 = bound(y0, 0, 1e28); + cx = bound(cx, 1, 1e18); + cy = bound(cy, 1, 1e18); + console.log("px", px); + console.log("py", py); + console.log("x0", x0); + console.log("y0", y0); + console.log("cx", cx); + console.log("cy", cy); + + // Note without -2 in the max bound, f() sometimes fails when x gets too close to centre. + // Note small x values lead to large y-values, which causes problems for both f() and fInverse(), so we cap it here + x = bound(x, 1e2 - 3, x0 - 3); + + uint256 y = CurveLib.f(x, px, py, x0, y0, cx); + console.log("y ", y); + uint256 xCalc = CurveLib.fInverse(y, px, py, x0, y0, cx); + console.log("xCalc", xCalc); + uint256 yCalc = CurveLib.f(xCalc, px, py, x0, y0, cx); + uint256 xBin = binarySearch(y, px, py, x0, y0, cx, 1, x0); + uint256 yBin = CurveLib.f(xBin, px, py, x0, y0, cx); + console.log("x ", x); + console.log("xCalc", xCalc); + console.log("xBin ", xBin); + console.log("y ", y); + console.log("yCalc", yCalc); + console.log("yBin ", yBin); + + if (x < type(uint112).max && y < type(uint112).max) { + assert(CurveLib.verify(xCalc, y, x0, y0, px, py, cx, cy)); + assert(int256(xCalc) - int256(xBin) <= 3 || int256(yCalc) - int256(yBin) <= 3); // suspect this is 2 wei error in fInverse() + 1 wei error in f() + } + } + +} \ No newline at end of file From cd64cb275f5c24850c894c417303ddd1d8bdca3f Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 20 Apr 2025 14:37:08 +0100 Subject: [PATCH 281/312] add binary search --- src/CurveLib.sol | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/CurveLib.sol b/src/CurveLib.sol index d3c1062..a7d310c 100644 --- a/src/CurveLib.sol +++ b/src/CurveLib.sol @@ -111,4 +111,32 @@ library CurveLib { function abs(int256 x) internal pure returns (uint256) { return uint256(x >= 0 ? x : -x); } + + function binarySearch( + uint256 y, + uint256 px, + uint256 py, + uint256 x0, + uint256 y0, + uint256 c, + uint256 xMin, + uint256 xMax + ) internal pure returns (uint256) { + if (xMin < 1) { + xMin = 1; + } + while (xMin < xMax) { + uint256 xMid = (xMin + xMax) / 2; + uint256 fxMid = f(xMid, px, py, x0, y0, c); + if (y >= fxMid) { + xMax = xMid; + } else { + xMin = xMid + 1; + } + } + if (y < f(xMin, px, py, x0, y0, c)) { + xMin += 1; + } + return xMin; + } } From 6a9535491d211712797ffb63df8ef1eee058bcaf Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Mon, 21 Apr 2025 14:08:27 +0100 Subject: [PATCH 282/312] add working fuzz test --- src/CurveLib.sol | 20 +++++++++++--------- test/CurveLib.t.sol | 26 ++++++++++++++++++++------ 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/CurveLib.sol b/src/CurveLib.sol index a7d310c..f0247d6 100644 --- a/src/CurveLib.sol +++ b/src/CurveLib.sol @@ -113,12 +113,14 @@ library CurveLib { } function binarySearch( - uint256 y, - uint256 px, - uint256 py, - uint256 x0, - uint256 y0, - uint256 c, + IEulerSwap.Params memory p, + uint256 newReserve1, + // uint256 y, + // uint256 px, + // uint256 py, + // uint256 x0, + // uint256 y0, + // uint256 c, uint256 xMin, uint256 xMax ) internal pure returns (uint256) { @@ -127,14 +129,14 @@ library CurveLib { } while (xMin < xMax) { uint256 xMid = (xMin + xMax) / 2; - uint256 fxMid = f(xMid, px, py, x0, y0, c); - if (y >= fxMid) { + uint256 fxMid = f(xMid, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX); + if (newReserve1 >= fxMid) { xMax = xMid; } else { xMin = xMid + 1; } } - if (y < f(xMin, px, py, x0, y0, c)) { + if (newReserve1 < f(xMin, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX)) { xMin += 1; } return xMin; diff --git a/test/CurveLib.t.sol b/test/CurveLib.t.sol index 0fa94be..05532b5 100644 --- a/test/CurveLib.t.sol +++ b/test/CurveLib.t.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.24; import "forge-std/Test.sol"; import "forge-std/console.sol"; import {EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; +import {IEulerSwap} from "../src/interfaces/IEulerSwap.sol"; import {CurveLib} from "../src/CurveLib.sol"; contract CurveLibTest is EulerSwapTestBase { @@ -15,9 +16,8 @@ contract CurveLibTest is EulerSwapTestBase { function test_fuzzfInverse(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) public - pure + view { - // Params px = 1e18; py = bound(py, 1, 1e36); @@ -32,6 +32,21 @@ contract CurveLibTest is EulerSwapTestBase { console.log("cx", cx); console.log("cy", cy); + IEulerSwap.Params memory p = IEulerSwap.Params({ + vault0: address(0), + vault1: address(0), + eulerAccount: address(0), + equilibriumReserve0: uint112(x0), + equilibriumReserve1: uint112(y0), + priceX: px, + priceY: py, + concentrationX: cx, + concentrationY: cy, + fee: 0, + protocolFee: 0, + protocolFeeRecipient: address(0) + }); + // Note without -2 in the max bound, f() sometimes fails when x gets too close to centre. // Note small x values lead to large y-values, which causes problems for both f() and fInverse(), so we cap it here x = bound(x, 1e2 - 3, x0 - 3); @@ -41,7 +56,7 @@ contract CurveLibTest is EulerSwapTestBase { uint256 xCalc = CurveLib.fInverse(y, px, py, x0, y0, cx); console.log("xCalc", xCalc); uint256 yCalc = CurveLib.f(xCalc, px, py, x0, y0, cx); - uint256 xBin = binarySearch(y, px, py, x0, y0, cx, 1, x0); + uint256 xBin = CurveLib.binarySearch(p, y, 1, x0); uint256 yBin = CurveLib.f(xBin, px, py, x0, y0, cx); console.log("x ", x); console.log("xCalc", xCalc); @@ -51,9 +66,8 @@ contract CurveLibTest is EulerSwapTestBase { console.log("yBin ", yBin); if (x < type(uint112).max && y < type(uint112).max) { - assert(CurveLib.verify(xCalc, y, x0, y0, px, py, cx, cy)); + assert(CurveLib.verify(p, xCalc, y)); assert(int256(xCalc) - int256(xBin) <= 3 || int256(yCalc) - int256(yBin) <= 3); // suspect this is 2 wei error in fInverse() + 1 wei error in f() } } - -} \ No newline at end of file +} From f16493df0c0d22db221753ba957a84cba737d8e7 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Mon, 21 Apr 2025 23:31:44 +0100 Subject: [PATCH 283/312] unchecked to reduce gas on fInverse() --- src/CurveLib.sol | 75 ++++++++++++++++++++++----------------------- test/CurveLib.t.sol | 16 ++++++++++ 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/src/CurveLib.sol b/src/CurveLib.sol index f0247d6..a762d23 100644 --- a/src/CurveLib.sol +++ b/src/CurveLib.sol @@ -39,40 +39,50 @@ library CurveLib { } } + /// @dev EulerSwap inverse function definition + /// Pre-conditions: 0 < x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 function fInverse(uint256 y, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { // components of quadratic equation - int256 B = int256((py * (y - y0) + (px - 1)) / px) - (2 * int256(c) - int256(1e18)) * int256(x0) / 1e18; + int256 B; uint256 C; uint256 fourAC; - if (x0 < 1e18) { - C = ((1e18 - c) * x0 * x0 + (1e18 - 1)) / 1e18; // upper bound of 1e28 for x0 means this is safe - fourAC = Math.mulDiv(4 * c, C, 1e18, Math.Rounding.Ceil); - } else { - C = Math.mulDiv((1e18 - c), x0 * x0, 1e36, Math.Rounding.Ceil); // upper bound of 1e28 for x0 means this is safe - fourAC = Math.mulDiv(4 * c, C, 1, Math.Rounding.Ceil); + unchecked { + B = int256((py * (y - y0) + (px - 1)) / px) - (2 * int256(c) - int256(1e18)) * int256(x0) / 1e18; + if (x0 >= 1e18) { + // if x0 >= 1, scale as normal + C = Math.mulDiv((1e18 - c), x0 * x0, 1e36, Math.Rounding.Ceil); + fourAC = 4 * c * C; + } else { + // if x0 < 1, then numbers get very small, so decrease scale to 1e18 to increase precision later + C = ((1e18 - c) * x0 * x0 + (1e18 - 1)) / 1e18; + fourAC = Math.mulDiv(4 * c, C, 1e18, Math.Rounding.Ceil); + } } - - // solve for the square root - uint256 absB = abs(B); + + uint256 absB = uint256(B >= 0 ? B : -B); uint256 squaredB; uint256 discriminant; uint256 sqrt; - if (absB > 1e33) { + if (absB < 1e36) { + // safe to use naive squaring + unchecked { + squaredB = absB * absB; + discriminant = squaredB + fourAC; // keep in 1e36 scale for increased precision ahead of sqrt + sqrt = Math.sqrt(discriminant); // drop back to 1e18 scale + sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; + } + } else { + // use scaled, overflow-safe path uint256 scale = computeScale(absB); squaredB = Math.mulDiv(absB / scale, absB, scale, Math.Rounding.Ceil); discriminant = squaredB + fourAC / (scale * scale); sqrt = Math.sqrt(discriminant); sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; sqrt = sqrt * scale; - } else { - squaredB = Math.mulDiv(absB, absB, 1, Math.Rounding.Ceil); - discriminant = squaredB + fourAC; // keep in 1e36 scale for increased precision ahead of sqrt - sqrt = Math.sqrt(discriminant); // drop back to 1e18 scale - sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; } uint256 x; @@ -90,40 +100,27 @@ library CurveLib { } function computeScale(uint256 x) internal pure returns (uint256 scale) { + // calculate number of bits in x uint256 bits = 0; - uint256 tmp = x; - - while (tmp > 0) { - tmp >>= 1; + while (x > 0) { + x >>= 1; bits++; } - // absB * absB must be <= 2^256 ⇒ bits(B) ≤ 128 + // 2^excessBits is how much we need to scale down to prevent overflow when squaring x if (bits > 128) { - uint256 excessBits = bits - 128; - // 2^excessBits is how much we need to scale down to prevent overflow + uint256 excessBits = bits - 128; scale = 1 << excessBits; } else { scale = 1; } } - function abs(int256 x) internal pure returns (uint256) { - return uint256(x >= 0 ? x : -x); - } - - function binarySearch( - IEulerSwap.Params memory p, - uint256 newReserve1, - // uint256 y, - // uint256 px, - // uint256 py, - // uint256 x0, - // uint256 y0, - // uint256 c, - uint256 xMin, - uint256 xMax - ) internal pure returns (uint256) { + function binarySearch(IEulerSwap.Params memory p, uint256 newReserve1, uint256 xMin, uint256 xMax) + internal + pure + returns (uint256) + { if (xMin < 1) { xMin = 1; } diff --git a/test/CurveLib.t.sol b/test/CurveLib.t.sol index 05532b5..fa2ccb0 100644 --- a/test/CurveLib.t.sol +++ b/test/CurveLib.t.sol @@ -14,6 +14,22 @@ contract CurveLibTest is EulerSwapTestBase { super.setUp(); } + function testGas_fInverse() public pure { + // Set representative values within valid bounds + uint256 px = 1e18; + uint256 py = 1e18; + uint256 x0 = 1e14; + uint256 y0 = 1e14; + uint256 c = 1e18; + + // Use CurveLib.f to get a valid y + uint256 x = 1e12; + uint256 y = CurveLib.f(x, px, py, x0, y0, c); + + // Measure gas of fInverse + CurveLib.fInverse(y, px, py, x0, y0, c); + } + function test_fuzzfInverse(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) public view From 6e4bb6da9bdb4efb766b795fa63b6f7046872561 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Tue, 22 Apr 2025 21:21:28 +0700 Subject: [PATCH 284/312] update scripts --- README.md | 6 ++++ script.old/json/SwapExactIn_input.json | 8 ----- {script.old => script}/DeployPool.s.sol | 34 +++++++++++++------ {script.old => script}/DeployProtocol.s.sol | 8 +++-- {script.old => script}/README.md | 0 {script.old => script}/ScriptUtil.s.sol | 0 {script.old => script}/SwapExactIn.s.sol | 6 ++-- .../json/DeployPool_input.json | 14 ++++---- .../json/DeployProtocol_input.json | 3 +- script/json/SwapExactIn_input.json | 7 ++++ 10 files changed, 55 insertions(+), 31 deletions(-) delete mode 100644 script.old/json/SwapExactIn_input.json rename {script.old => script}/DeployPool.s.sol (70%) rename {script.old => script}/DeployProtocol.s.sol (75%) rename {script.old => script}/README.md (100%) rename {script.old => script}/ScriptUtil.s.sol (100%) rename {script.old => script}/SwapExactIn.s.sol (90%) rename {script.old => script}/json/DeployPool_input.json (51%) rename {script.old => script}/json/DeployProtocol_input.json (50%) create mode 100644 script/json/SwapExactIn_input.json diff --git a/README.md b/README.md index f1ebc33..0c6d28f 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,12 @@ forge doc --serve --port 4000 - EulerSwapPeriphery: 0x813D74E832b3d9E9451d8f0E871E877edf2a5A5f - USDT-USDT pool: 0x2bFED8dBEb8e6226a15300AC77eE9130E52410fE +------ with Uniswap hook contracts (latest) + +- EulerSwap implementation: 0x0B8CD42911551882638f4C762A66570e1fAc624f +- EulerSwapFactory: 0x52177559e6430396b9A7E2176Ef33b4e4052D125 +- EulerSwapPeriphery: 0x9F27Bc363DB128cdC349CA54671E6Fbe2bE194D0 +- USDT-USDT pool: 0x13f627635CD96a2A75c2efBDba979172cAb2E888 ## Safety diff --git a/script.old/json/SwapExactIn_input.json b/script.old/json/SwapExactIn_input.json deleted file mode 100644 index 3836023..0000000 --- a/script.old/json/SwapExactIn_input.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "periphery": "0x813D74E832b3d9E9451d8f0E871E877edf2a5A5f", - "pool": "0x2bFED8dBEb8e6226a15300AC77eE9130E52410fE", - "tokenIn": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", - "tokenOut": "0xdAC17F958D2ee523a2206206994597C13D831ec7", - "amountIn": 4e6, - "amountOutMin": 3.9e6 -} \ No newline at end of file diff --git a/script.old/DeployPool.s.sol b/script/DeployPool.s.sol similarity index 70% rename from script.old/DeployPool.s.sol rename to script/DeployPool.s.sol index 63da318..ff60726 100644 --- a/script.old/DeployPool.s.sol +++ b/script/DeployPool.s.sol @@ -4,6 +4,9 @@ pragma solidity ^0.8.0; import {ScriptUtil} from "./ScriptUtil.s.sol"; import {IEulerSwapFactory, IEulerSwap, EulerSwapFactory} from "../src/EulerSwapFactory.sol"; import {IEVC, IEulerSwap} from "../src/EulerSwap.sol"; +import {HookMiner} from "../test/utils/HookMiner.sol"; +import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; +import {MetaProxyDeployer} from "../src/utils/MetaProxyDeployer.sol"; /// @title Script to deploy new pool. contract DeployPool is ScriptUtil { @@ -23,21 +26,32 @@ contract DeployPool is ScriptUtil { eulerAccount: eulerAccount, equilibriumReserve0: uint112(vm.parseJsonUint(json, ".equilibriumReserve0")), equilibriumReserve1: uint112(vm.parseJsonUint(json, ".equilibriumReserve1")), - currReserve0: uint112(vm.parseJsonUint(json, ".currReserve0")), - currReserve1: uint112(vm.parseJsonUint(json, ".currReserve1")), - fee: vm.parseJsonUint(json, ".fee") - }); - IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams({ priceX: vm.parseJsonUint(json, ".priceX"), priceY: vm.parseJsonUint(json, ".priceY"), concentrationX: vm.parseJsonUint(json, ".concentrationX"), - concentrationY: vm.parseJsonUint(json, ".concentrationY") + concentrationY: vm.parseJsonUint(json, ".concentrationY"), + fee: vm.parseJsonUint(json, ".fee"), + protocolFee: vm.parseJsonUint(json, ".protocolFee"), + protocolFeeRecipient: vm.parseJsonAddress(json, ".protocolFeeRecipient") + }); + IEulerSwap.InitialState memory initialState = IEulerSwap.InitialState({ + currReserve0: uint112(vm.parseJsonUint(json, ".currReserve0")), + currReserve1: uint112(vm.parseJsonUint(json, ".currReserve1")) }); - bytes32 salt = bytes32(uint256(vm.parseJsonUint(json, ".salt"))); + address eulerSwapImpl = vm.parseJsonAddress(json, ".eulerSwapImplementation"); - IEVC evc = IEVC(factory.EVC()); - address predictedPoolAddress = factory.computePoolAddress(poolParams, curveParams, salt); + bytes memory creationCode = MetaProxyDeployer.creationCodeMetaProxy(eulerSwapImpl, abi.encode(poolParams)); + (address predictedPoolAddress, bytes32 salt) = HookMiner.find( + address(address(factory)), + eulerAccount, + uint160( + Hooks.BEFORE_INITIALIZE_FLAG | Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_SWAP_RETURNS_DELTA_FLAG + | Hooks.BEFORE_ADD_LIQUIDITY_FLAG + ), + creationCode + ); + IEVC evc = IEVC(factory.EVC()); IEVC.BatchItem[] memory items = new IEVC.BatchItem[](2); items[0] = IEVC.BatchItem({ @@ -50,7 +64,7 @@ contract DeployPool is ScriptUtil { onBehalfOfAccount: eulerAccount, targetContract: address(factory), value: 0, - data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, curveParams, salt)) + data: abi.encodeCall(EulerSwapFactory.deployPool, (poolParams, initialState, salt)) }); vm.startBroadcast(eulerAccount); diff --git a/script.old/DeployProtocol.s.sol b/script/DeployProtocol.s.sol similarity index 75% rename from script.old/DeployProtocol.s.sol rename to script/DeployProtocol.s.sol index b0db2bd..1ffb1fc 100644 --- a/script.old/DeployProtocol.s.sol +++ b/script/DeployProtocol.s.sol @@ -5,6 +5,7 @@ import {ScriptUtil} from "./ScriptUtil.s.sol"; import {EulerSwapFactory} from "../src/EulerSwapFactory.sol"; import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; +import {EulerSwap} from "../src/EulerSwap.sol"; /// @title Script to deploy EulerSwapFactory & EulerSwapPeriphery. contract DeployProtocol is ScriptUtil { @@ -19,13 +20,14 @@ contract DeployProtocol is ScriptUtil { address evc = vm.parseJsonAddress(json, ".evc"); address poolManager = vm.parseJsonAddress(json, ".poolManager"); - address factory = vm.parseJsonAddress(json, ".factory"); + address evkFactory = vm.parseJsonAddress(json, ".evkFactory"); + address feeOwner = vm.parseJsonAddress(json, ".feeOwner"); vm.startBroadcast(deployerAddress); - new EulerSwapFactory(IPoolManager(poolManager), evc, factory); + address eulerSwapImpl = address(new EulerSwap(evc, poolManager)); + new EulerSwapFactory(evc, evkFactory, eulerSwapImpl, feeOwner); new EulerSwapPeriphery(); - vm.stopBroadcast(); } } diff --git a/script.old/README.md b/script/README.md similarity index 100% rename from script.old/README.md rename to script/README.md diff --git a/script.old/ScriptUtil.s.sol b/script/ScriptUtil.s.sol similarity index 100% rename from script.old/ScriptUtil.s.sol rename to script/ScriptUtil.s.sol diff --git a/script.old/SwapExactIn.s.sol b/script/SwapExactIn.s.sol similarity index 90% rename from script.old/SwapExactIn.s.sol rename to script/SwapExactIn.s.sol index bfc51e7..f2349c7 100644 --- a/script.old/SwapExactIn.s.sol +++ b/script/SwapExactIn.s.sol @@ -8,7 +8,6 @@ import {EulerSwapPeriphery} from "../src/EulerSwapPeriphery.sol"; import {ScriptUtil} from "./ScriptUtil.s.sol"; - contract SwapExactIn is ScriptUtil { using SafeERC20 for IERC20; @@ -26,13 +25,14 @@ contract SwapExactIn is ScriptUtil { address tokenIn = vm.parseJsonAddress(json, ".tokenIn"); address tokenOut = vm.parseJsonAddress(json, ".tokenOut"); uint256 amountIn = vm.parseJsonUint(json, ".amountIn"); - uint256 amountOutMin = vm.parseJsonUint(json, ".amountOutMin"); + + uint256 amountOutMin = periphery.quoteExactInput(address(pool), tokenIn, tokenOut, amountIn); vm.startBroadcast(swapperAddress); IERC20(tokenIn).forceApprove(address(periphery), amountIn); - periphery.swapExactIn(address(pool), tokenIn, tokenOut, amountIn, amountOutMin); + periphery.swapExactIn(address(pool), tokenIn, tokenOut, amountIn, swapperAddress, amountOutMin, 0); vm.stopBroadcast(); } diff --git a/script.old/json/DeployPool_input.json b/script/json/DeployPool_input.json similarity index 51% rename from script.old/json/DeployPool_input.json rename to script/json/DeployPool_input.json index bd53048..3fd506b 100644 --- a/script.old/json/DeployPool_input.json +++ b/script/json/DeployPool_input.json @@ -1,15 +1,17 @@ { - "factory": "0xF75548aF02f1928CbE9015985D4Fcbf96d728544", - "salt": "1", + "factory": "0x52177559e6430396b9A7E2176Ef33b4e4052D125", + "eulerSwapImplementation": "0x0B8CD42911551882638f4C762A66570e1fAc624f", "vault0": "0xa66957e58b60d6b92b850c8773a9ff9b0ba96a65", "vault1": "0x4212e01c7c8e1c21dea6030c74ae2084f5337bd1", "equilibriumReserve0": 2000e6, "equilibriumReserve1": 2000e6, - "currReserve0": 2000e6, - "currReserve1": 2000e6, - "fee": 0, "priceX": 1e18, "priceY": 1e18, "concentrationX": 0.97e18, - "concentrationY": 0.97e18 + "concentrationY": 0.97e18, + "fee": 0, + "protocolFee": 0, + "protocolFeeRecipient": "0x0000000000000000000000000000000000000000", + "currReserve0": 2000e6, + "currReserve1": 2000e6 } \ No newline at end of file diff --git a/script.old/json/DeployProtocol_input.json b/script/json/DeployProtocol_input.json similarity index 50% rename from script.old/json/DeployProtocol_input.json rename to script/json/DeployProtocol_input.json index 80096a8..8209a02 100644 --- a/script.old/json/DeployProtocol_input.json +++ b/script/json/DeployProtocol_input.json @@ -1,5 +1,6 @@ { "evc": "0x0C9a3dd6b8F28529d72d7f9cE918D493519EE383", "poolManager": "0x000000000004444c5dc75cB358380D2e3dE08A90", - "factory": "0xF75548aF02f1928CbE9015985D4Fcbf96d728544" + "evkFactory": "0x29a56a1b8214D9Cf7c5561811750D5cBDb45CC8e", + "feeOwner": "0x603765f9e9B8E3CBACbdf7A6e963B7EAD77AE86f" } diff --git a/script/json/SwapExactIn_input.json b/script/json/SwapExactIn_input.json new file mode 100644 index 0000000..63ebd4b --- /dev/null +++ b/script/json/SwapExactIn_input.json @@ -0,0 +1,7 @@ +{ + "periphery": "0x9F27Bc363DB128cdC349CA54671E6Fbe2bE194D0", + "pool": "0x13f627635CD96a2A75c2efBDba979172cAb2E888", + "tokenIn": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "tokenOut": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "amountIn": 4e6 +} \ No newline at end of file From c7d7898e96a0079a5b09b08082386f622e91ab12 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 22 Apr 2025 21:23:10 -0400 Subject: [PATCH 285/312] fix path --- test/CurveLib.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CurveLib.t.sol b/test/CurveLib.t.sol index fa2ccb0..1ebaa67 100644 --- a/test/CurveLib.t.sol +++ b/test/CurveLib.t.sol @@ -5,7 +5,7 @@ import "forge-std/Test.sol"; import "forge-std/console.sol"; import {EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; import {IEulerSwap} from "../src/interfaces/IEulerSwap.sol"; -import {CurveLib} from "../src/CurveLib.sol"; +import {CurveLib} from "../src/libraries/CurveLib.sol"; contract CurveLibTest is EulerSwapTestBase { EulerSwap public eulerSwap; From c650fad08badf76c93affe08b0b4a28f512b8b0c Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 22 Apr 2025 21:23:12 -0400 Subject: [PATCH 286/312] some dev comments --- src/libraries/CurveLib.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/CurveLib.sol b/src/libraries/CurveLib.sol index 32e3451..a1879b8 100644 --- a/src/libraries/CurveLib.sol +++ b/src/libraries/CurveLib.sol @@ -99,6 +99,7 @@ library CurveLib { } } + /// @dev Utility to derive optimal scale for computations in fInverse function computeScale(uint256 x) internal pure returns (uint256 scale) { // calculate number of bits in x uint256 bits = 0; @@ -116,6 +117,7 @@ library CurveLib { } } + /// @dev Less efficient method to compute fInverse. Useful for testing. function binarySearch(IEulerSwap.Params memory p, uint256 newReserve1, uint256 xMin, uint256 xMax) internal pure From 510ccf370013b47c1d3628966c93d9a30faa2881 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 22 Apr 2025 21:23:40 -0400 Subject: [PATCH 287/312] forge fmt --- src/libraries/CurveLib.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/CurveLib.sol b/src/libraries/CurveLib.sol index a1879b8..f4d0fdc 100644 --- a/src/libraries/CurveLib.sol +++ b/src/libraries/CurveLib.sol @@ -51,7 +51,7 @@ library CurveLib { uint256 C; uint256 fourAC; unchecked { - B = int256((py * (y - y0) + (px - 1)) / px) - (2 * int256(c) - int256(1e18)) * int256(x0) / 1e18; + B = int256((py * (y - y0) + (px - 1)) / px) - (2 * int256(c) - int256(1e18)) * int256(x0) / 1e18; if (x0 >= 1e18) { // if x0 >= 1, scale as normal C = Math.mulDiv((1e18 - c), x0 * x0, 1e36, Math.Rounding.Ceil); @@ -62,7 +62,7 @@ library CurveLib { fourAC = Math.mulDiv(4 * c, C, 1e18, Math.Rounding.Ceil); } } - + uint256 absB = uint256(B >= 0 ? B : -B); uint256 squaredB; uint256 discriminant; @@ -74,7 +74,7 @@ library CurveLib { discriminant = squaredB + fourAC; // keep in 1e36 scale for increased precision ahead of sqrt sqrt = Math.sqrt(discriminant); // drop back to 1e18 scale sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; - } + } } else { // use scaled, overflow-safe path uint256 scale = computeScale(absB); @@ -110,7 +110,7 @@ library CurveLib { // 2^excessBits is how much we need to scale down to prevent overflow when squaring x if (bits > 128) { - uint256 excessBits = bits - 128; + uint256 excessBits = bits - 128; scale = 1 << excessBits; } else { scale = 1; From 1a7e7e0e264fedf514f68de275e28906ed01bb5f Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 18 Apr 2025 12:08:13 -0400 Subject: [PATCH 288/312] update architecture docs, todo --- TODO | 6 --- docs/architecture.md | 126 +++++++++++++++++++++---------------------- 2 files changed, 62 insertions(+), 70 deletions(-) diff --git a/TODO b/TODO index 889a0f4..f87274b 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,3 @@ -* docs - ! new flow for activate - ! document that periphery depends on non-malicious eulerSwap instances - ! limitations of getLimits -* update deploy scripts -* small cleanups in CurveLib ? tighten up getLimits bounds TESTING diff --git a/docs/architecture.md b/docs/architecture.md index 2415cde..387b89c 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -8,109 +8,107 @@ Each EulerSwap instance is a lightweight smart contract that functions as an [EV When a user initiates a swap, the EulerSwap operator borrows the required output token using the input token as collateral. The operator’s internal AMM curve governs the exchange rate, ensuring deep liquidity over short timeframes while maintaining a balance between collateral and debt over the long term. +Swapping can be performed by invoking the EulerSwap instance, either through a Uniswap2-compatible `swap()` function or as a [Uniswap4 hook](https://docs.uniswap.org/contracts/v4/concepts/hooks). + ## Code structure -EulerSwap’s code is split into two main smart contracts: +EulerSwap is split into the following main contracts: + +* `EulerSwap`: Contract that is installed as an EVC operator by liquidity providers, and is also invoked by swappers in order to execute a swap. + * `UniswapHook`: The functions required so that the EulerSwap instance can function as a Uniswap4 hook. +* `EulerSwapFactory`: Factory contract for creating `EulerSwap` instances and for querying existing instances. +* `EulerSwapPeriphery`: This is a wrapper contract for quoting and performing swaps, while handling approvals, slippage, etc. -### EulerSwap core (`EulerSwap.sol`) +The above contracts depend on libraries: -- Handles collateralization via EVC and Euler credit vaults. -- Implements AMM curve invariant checks through the `verify()` function. +* `CtxLib`: Allows access to the `EulerSwap` context: Structured storage and the instance parameters +* `FundsLib`: Moving tokens: approvals and transfers in/out +* `CurveLib`: Mathematical routines for calculating the EulerSwap curve +* `QuoteLib`: Computing quotes. This involves invoking the logic from `CurveLib`, as well as taking into account other limitations such as vault utilisation, supply caps, etc. -### EulerSwap periphery (`EulerSwapPeriphery.sol`) +And some utilities: -- Provides simplified functions for retrieving swap quotes from the AMM curve. -- Acts as a convenience layer for external integrations. +* `MetaProxyDeployer`: Deploys EIP-3448-style proxies. +* `ProtocolFee`: The factory stores protocol fee parameters that will affect subsequently created `EulerSwap` instances. These can be changed by an owner. ## Operational flow The following steps outline how an EulerSwap operator is created and configured: 1. Deposit initial liquidity into one or both of the underlying credit vaults to enable swaps. -2. Deploy an instance of EulerSwap, specifying AMM curve parameters and the `fee`. -3. Set the [virtual reserves](#virtual-reserves) by invoking `setVirtualReserves()`. -4. Install the EulerSwap contract as an operator for the user's account. -5. Invoke the `configure()` function on the EulerSwap contract. +1. Choose the desired pool parameters (`IEulerSwap.Params` struct). The `protocolFee` and `protocolFeeRecipient` must be read from the factory. +1. [Mine](https://docs.uniswap.org/contracts/v4/guides/hooks/hook-deployment#hook-miner) a salt such that the predicted address of the `EulerSwap` instance will be deployed with the correct flags. +1. Install the above address as an EVC operator, ensuring that any previous `EulerSwap` operators are uninstalled. +1. Invoke `deployPool()` on the EulerSwap factory. + +## Metaproxies + +Each `EulerSwap` instance is a lightweight proxy, roughly modelled after [EIP-3448](https://eips.ethereum.org/EIPS/eip-3448). The only difference is that EIP-3448 appends the length of the metadata, whereas we don't, since it is a fixed size. + +When an `EulerSwap` instance is created, the `IEulerSwap.Params` struct is ABI encoded and provided as the proxy metadata. This is provided to the implementation contract as trailing calldata via `delegatecall`. This allows the parameters to be accessed cheaply when servicing a swap, compared to if they had to be read from storage. + +## Curve Parameters + +Traditional AMMs hold dedicated reserves of each of the supported tokens, which inherently limit the sizes of swaps that can be serviced. For example, if an AMM has 100 units of a token available, there is no possible price that can convince it to send more than 100 units. -Once configured, the EulerSwap contract can process swaps. When a user invokes `swap()`, the contract facilitates borrowing and transfers between the underlying vaults as dictated by the AMM curve. +Since EulerSwap does not have dedicated reserves, its swapping limits must be defined in another way. This is accomplished by having the EulerSwap operator define an abstract curve. The domain of this curve defines the swap limits, which can be considered the virtual reserves. -### Virtual reserves +The abstract curve is centred on an *equilibrium point*. This is parameterised by two equilibrium reserves values. These specify the magnitude of the virtual reserves, and function as hard limits on the supported swap sizes. They are often equal, but do not necessarily have to be (for instance, if the two vaults have asymmetric LTVs). -The initial deposits in the vaults provide starting liquidity and facilitate swaps. In traditional AMMs like Uniswap, these balances are known as _reserves_. -However, relying solely on these assets would impose a hard limit on swap size. To overcome this, EulerSwap introduces _virtual reserves_, allowing the AMM to extend its effective liquidity by borrowing against its real reserves. +At the equilibrium point, the marginal swap price is defined by the ratio of two parameters `priceX` and `priceY`. Generally operators will choose the price ratio at equilibrium to be the asset's pegged price, or the wider market price. The prices should also compensate for a difference in token decimals, if any. -Virtual reserves control the maximum debt that the EulerSwap contract will attempt to acquire on each of its two vaults. Each vault can be configured independently. For example, if the initial investment has a NAV of \$1000, and virtual reserves are configured at \$5000 for each vault, then the maximum LTV loan that the AMM will support will be `5000/6000 = 0.8333`. In order to leave a safety buffer, it is recommended to select a maximum LTV that is below the borrowing LTV of the vault. Note that it depends on the [curve](#curves) if the maximum LTV can actually be achieved. A constant product curve will only approach these reserve levels asymptotically, since each unit will get more and more expensive. However, with a constant sum curve, the maximum LTV can be achieved directly. +The curve is also parameterised by two **concentration factors** between `0` and `1`. These control the shape of each side of the curve (to the left of the equilibrium point, and to the right). The curve shape is essentially a blend of constant product and constant sum. The closer to `0` the more the curve resembles constant product, and the closer to `1`, constant sum. -### Reserve synchronisation +In most cases (except with concentration factor of `1`), virtual reserves can never be fully depleted. The limits can only be approached asymptotically. -The EulerSwap contract tracks what it believes the reserves to be by caching their values in storage. These reserves are updated on each swap. However, since the balance is not actually held by the EulerSwap contract (it is simply an operator), the actual underlying balances may get out of sync. This can happen gradually as interest is accrued, or suddenly if the holder moves funds or the position is liquidated. When this occurs, the EulerSwap operator should be uninstalled and a new, updated one installed instead. +Generally it is expected that arbitrage will favour returning the reserves to the equilbrium point. The price and the convex constant-product-like curve shape encourages this. If the price at equilibrium is accurate then the equilbrium point always represents the point of minimum NAV for the operator, and this point is arbitrage-free. -## Components +## Initial State -### **1. Core contracts** +The curve as parameterised above is an abstract geometric shape. In order to actually make use of it, you must install it on an account that already has some existing conditions. For example, it may already have a borrow, or it may have unequal deposits in the two vaults. -#### **EulerSwap contract** +To be as flexible as possible, EulerSwap allows you to specify the **current reserves** when you are instantiating a pool. -The `EulerSwap` contract is the core of EulerSwap and is responsible for: +If the current state of the account is where you wish the equilbrium point to be, then you should make the current reserves the same as the equilibrium reserves. Otherwise, the current reserves can be offset (take from one side and give to the other) to specify a new equilibrium point that swapping activity should take you to. -- Managing liquidity reserves. -- Executing token swaps based on the EulerSwap curve. -- Enforcing collateralization through EVC. -- Maintaining vault and asset associations. +Note that there may be a race condition when removing one swap operator and installing another. In between when you've calculated the current reserves and when you've actually created and installed the new operator, a swap may occur that modifies the account state. To avoid this, a wrapper contract should be used that calculates the current reserves. Or, more simply, just verifies that the account state was as observed by the operator and otherwise reverts. -##### **Key features** -- Implements a unique **swapping curve** that ensures efficient liquidity provision. -- Handles **collateralized borrowing** via vaults. -- Enforces a **fee multiplier** to apply swap fees. -- Implements a **non-reentrant mechanism** to prevent recursive calls. +## Fees -##### **Key functions** +Swapping fees are charged by requiring the swapper to pay slightly more of the input token than is proscribed by the curve parameters. This extra amount is simply directly deposited into the vaults on behalf of the EulerSwap account. This means that it has the effect of increasing the account's NAV, but does not change the shape of the curve itself. The curve is always static, per EulerSwap instance. -- `activate()`: Initializes vault approvals and enables collateral. -- `swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data)`: Performs asset swaps and enforces curve constraints. -- `verify(uint256 newReserve0, uint256 newReserve1)`: Ensures reserves conform to the defined curve. -- `f(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c)`: Defines the EulerSwap curve formula for swaps. -### **2. Periphery contracts** +## Reserve desynchronisation -#### **EulerSwapPeriphery contract** +The EulerSwap contract tracks the current reserves in storage. After a swap, the amount of received tokens is added to the current reserves, and the amount of sent tokens subtracted. Since the reserves are not allowed to go negative, this implies a hard limit on the swap sizes. -The `EulerSwapPeriphery` contract extends the functionality of the core EulerSwap contract by providing: +While these reserves track the state of the world as influenced by swaps, they can get out-of-sync with the actual account for various reasons: -- **Swap price quotations** before execution. -- **Liquidity checks** to ensure solvency before transactions. -- **Binary search mechanisms** for dynamic price calculation. +* Interest can be accrued, either increasing or decreasing the account's NAV. +* Swap fees are not tracked, and instead increase the account's NAV. +* The account could be liquidated. +* The account owner could manually add or remove funds, repay loans, etc. -##### **Key functions** +In order to correct these desynchronisations, the EulerSwap operator should be uninstalled and a new, updated one installed instead. -- `quoteExactInput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountIn)`: Estimates the output amount for a given input. -- `quoteExactOutput(address eulerSwap, address tokenIn, address tokenOut, uint256 amountOut)`: Estimates the required input amount to receive a specified output. -- `computeQuote(IEulerSwap eulerSwap, address tokenIn, address tokenOut, uint256 amount, bool exactIn)`: A high-level function to compute swaps while enforcing fee multipliers. -- `binarySearch(IEulerSwap eulerSwap, uint112 reserve0, uint112 reserve1, uint256 amount, bool exactIn, bool asset0IsInput)`: Uses binary search to determine an optimal swap amount along the curve. -### **3. Vault integration** +## getLimits -EulerSwap integrates with **Ethereum Vault Connector (EVC)** to enable collateralized trading. Each liquidity vault manages asset balances, borrowing, and repayment, ensuring: +Although the virtual reserves specify a hard limit for swaps, there may be other implicit limits that are even lower: -- **Controlled debt exposure** -- **Dynamic liquidity reserves** -- **Secure vault interactions** +* The vaults have high utilisation and cannot service large borrows or withdrawals +* The vaults have supply and/or borrow caps +* The operator may have been uninstalled -### **4. Security mechanisms** +There is a function `getLimits` that can take these into account. This function itself is an upper-bound and the values it returns may not be swappable either, in particular if the curve shape does not allow it. However, it makes a best effort and this function can be used to rapidly exclude pools that are currently unable to service a given size swap. -- **Non-reentrant protection**: Ensures swaps do not trigger recursive calls. -- **Collateral verification**: Uses EVC to verify and adjust collateral balances. -- **Curve constraints enforcement**: Prevents swap execution that violates the defined curve invariant. -- **Precision safeguards**: Fixed-point arithmetic (`1e18` scaling) ensures precision in calculations. -## Summary +## Swapper Security -EulerSwap’s architecture is designed for **efficient, secure, and collateral-backed trading** with a custom **swapping curve**. The system leverages: +When swapping with an EulerSwap instance, users should always make sure that they received the desired amount of output tokens in one of two ways: -- **EulerSwap** as the core AMM contract. -- **EulerSwapPeriphery** for auxiliary quoting and validations. -- **Ethereum Vault Connector (EVC)** for collateralized vault management. -- **Security-focused design** to prevent vulnerabilities in asset handling. +* Actually checking your output token balances before and after and making sure they increased by an amount to satisfy slippage. +* Ensure that the EulerSwap code is a trusted instance that will send the specified output amount or revert if not possible. This can be done by making sure an instance was created by a trusted factory. -This modular and scalable architecture ensures that EulerSwap provides robust DeFi trading functionality while maintaining security and efficiency. +In particular, note that the periphery does not perform either of these checks, so if you use the periphery for swapping, you should ensure that you only interact with EulerSwap instances created by a known-good factory. From 766f2d72ca8afe086c6f393907321e75a5fb7148 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 23 Apr 2025 11:58:54 -0400 Subject: [PATCH 289/312] from Michael: helper function to compute the post-swap derivative (marginal price) --- src/libraries/CurveLib.sol | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libraries/CurveLib.sol b/src/libraries/CurveLib.sol index f4d0fdc..f999bd1 100644 --- a/src/libraries/CurveLib.sol +++ b/src/libraries/CurveLib.sol @@ -140,4 +140,15 @@ library CurveLib { } return xMin; } + + /// @dev EulerSwap derivative helper function to find the price after a swap + /// Pre-conditions: 0 < x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 + function df_dx(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) + internal + pure + returns (int256) + { + uint256 r = Math.mulDiv(x0 * x0 / x, 1e18, x, Math.Rounding.Ceil); + return -int256(px * (c + (1e18 - c) * r / 1e18) / py); + } } From dd99196e242c151674f37c5e756174bd98d2fb18 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Wed, 23 Apr 2025 13:54:13 -0400 Subject: [PATCH 290/312] minor doc edits --- docs/architecture.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 387b89c..8aefb20 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -53,11 +53,11 @@ Traditional AMMs hold dedicated reserves of each of the supported tokens, which Since EulerSwap does not have dedicated reserves, its swapping limits must be defined in another way. This is accomplished by having the EulerSwap operator define an abstract curve. The domain of this curve defines the swap limits, which can be considered the virtual reserves. -The abstract curve is centred on an *equilibrium point*. This is parameterised by two equilibrium reserves values. These specify the magnitude of the virtual reserves, and function as hard limits on the supported swap sizes. They are often equal, but do not necessarily have to be (for instance, if the two vaults have asymmetric LTVs). +The abstract curve is centred on an *equilibrium point*. This is parameterised by two equilibrium reserves values. These specify the magnitude of the virtual reserves, and are effectively hard limits on the supported swap sizes. They are often equal, but do not necessarily have to be (for instance, if the two vaults have asymmetric LTVs). At the equilibrium point, the marginal swap price is defined by the ratio of two parameters `priceX` and `priceY`. Generally operators will choose the price ratio at equilibrium to be the asset's pegged price, or the wider market price. The prices should also compensate for a difference in token decimals, if any. -The curve is also parameterised by two **concentration factors** between `0` and `1`. These control the shape of each side of the curve (to the left of the equilibrium point, and to the right). The curve shape is essentially a blend of constant product and constant sum. The closer to `0` the more the curve resembles constant product, and the closer to `1`, constant sum. +Finally, the curve is parameterised by two **concentration factors** between `0` and `1`. Each corresponds to the portion of the curve to the left or right of the equilibrium point. These factors control the shape of each side of the curve (to the left of the equilibrium point, and to the right). These parameters change the curve shape according to a blend of constant product and constant sum. The closer to `0` the more the curve resembles a constant product, and the closer to `1`, constant sum. In most cases (except with concentration factor of `1`), virtual reserves can never be fully depleted. The limits can only be approached asymptotically. @@ -76,7 +76,9 @@ Note that there may be a race condition when removing one swap operator and inst ## Fees -Swapping fees are charged by requiring the swapper to pay slightly more of the input token than is proscribed by the curve parameters. This extra amount is simply directly deposited into the vaults on behalf of the EulerSwap account. This means that it has the effect of increasing the account's NAV, but does not change the shape of the curve itself. The curve is always static, per EulerSwap instance. +Swapping fees are charged by requiring the swapper to pay slightly more of the input token than is required by the curve parameters. This extra amount is simply directly deposited into the vaults on behalf of the EulerSwap account. This means that it has the effect of increasing the account's NAV, but does not change the shape of the curve itself. The curve is always static, per EulerSwap instance. + +When an EulerSwap instance is created, a **protocol fee** parameter may be installed by the factory. This portion of the collected fees are routed to a protocol fee recipient. An administrator of the factory can change the the protocol fee and recipient for future created EulerSwap instances, although previously created instances will not be updated retroactively. ## Reserve desynchronisation @@ -90,7 +92,7 @@ While these reserves track the state of the world as influenced by swaps, they c * The account could be liquidated. * The account owner could manually add or remove funds, repay loans, etc. -In order to correct these desynchronisations, the EulerSwap operator should be uninstalled and a new, updated one installed instead. +In order to correct any desynchronisation, the EulerSwap operator should be uninstalled and a new, updated one installed instead. ## getLimits @@ -101,7 +103,7 @@ Although the virtual reserves specify a hard limit for swaps, there may be other * The vaults have supply and/or borrow caps * The operator may have been uninstalled -There is a function `getLimits` that can take these into account. This function itself is an upper-bound and the values it returns may not be swappable either, in particular if the curve shape does not allow it. However, it makes a best effort and this function can be used to rapidly exclude pools that are currently unable to service a given size swap. +There is a function `getLimits` that can take these into account. This function itself is an upper-bound and the values it returns may not be swappable either, in particular if the curve shape does not allow it. However, it makes a best effort and this function can be used to rapidly exclude pools that are definitely unable to service a given size swap. ## Swapper Security From fb3c1e184c55d71143e083dbc4e3bde6cda38c45 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Thu, 24 Apr 2025 11:53:46 -0400 Subject: [PATCH 291/312] move functions from CurveLib into more appropriate places: new CurveExtras library, and tests --- docs/architecture.md | 1 + src/libraries/CurveExtrasLib.sol | 17 ++++++++++++++++ src/libraries/CurveLib.sol | 35 -------------------------------- test/CurveLib.t.sol | 32 +++++++++++++++++++++++++++-- 4 files changed, 48 insertions(+), 37 deletions(-) create mode 100644 src/libraries/CurveExtrasLib.sol diff --git a/docs/architecture.md b/docs/architecture.md index 8aefb20..6b4fc2a 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -25,6 +25,7 @@ The above contracts depend on libraries: * `FundsLib`: Moving tokens: approvals and transfers in/out * `CurveLib`: Mathematical routines for calculating the EulerSwap curve * `QuoteLib`: Computing quotes. This involves invoking the logic from `CurveLib`, as well as taking into account other limitations such as vault utilisation, supply caps, etc. +* `CurveExtrasLib`: Extra utilities for curve computations. Not used in the EulerSwap itself, but potentially useful for integrators. And some utilities: diff --git a/src/libraries/CurveExtrasLib.sol b/src/libraries/CurveExtrasLib.sol new file mode 100644 index 0000000..46804c9 --- /dev/null +++ b/src/libraries/CurveExtrasLib.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.27; + +import {Math} from "openzeppelin-contracts/utils/math/Math.sol"; + +library CurveExtrasLib { + /// @dev EulerSwap derivative helper function to find the price after a swap + /// Pre-conditions: 0 < x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 + function df_dx(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) + internal + pure + returns (int256) + { + uint256 r = Math.mulDiv(x0 * x0 / x, 1e18, x, Math.Rounding.Ceil); + return -int256(px * (c + (1e18 - c) * r / 1e18) / py); + } +} diff --git a/src/libraries/CurveLib.sol b/src/libraries/CurveLib.sol index f999bd1..dca5a13 100644 --- a/src/libraries/CurveLib.sol +++ b/src/libraries/CurveLib.sol @@ -116,39 +116,4 @@ library CurveLib { scale = 1; } } - - /// @dev Less efficient method to compute fInverse. Useful for testing. - function binarySearch(IEulerSwap.Params memory p, uint256 newReserve1, uint256 xMin, uint256 xMax) - internal - pure - returns (uint256) - { - if (xMin < 1) { - xMin = 1; - } - while (xMin < xMax) { - uint256 xMid = (xMin + xMax) / 2; - uint256 fxMid = f(xMid, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX); - if (newReserve1 >= fxMid) { - xMax = xMid; - } else { - xMin = xMid + 1; - } - } - if (newReserve1 < f(xMin, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX)) { - xMin += 1; - } - return xMin; - } - - /// @dev EulerSwap derivative helper function to find the price after a swap - /// Pre-conditions: 0 < x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 - function df_dx(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) - internal - pure - returns (int256) - { - uint256 r = Math.mulDiv(x0 * x0 / x, 1e18, x, Math.Rounding.Ceil); - return -int256(px * (c + (1e18 - c) * r / 1e18) / py); - } } diff --git a/test/CurveLib.t.sol b/test/CurveLib.t.sol index 1ebaa67..50d5178 100644 --- a/test/CurveLib.t.sol +++ b/test/CurveLib.t.sol @@ -32,7 +32,7 @@ contract CurveLibTest is EulerSwapTestBase { function test_fuzzfInverse(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 cx, uint256 cy) public - view + pure { // Params px = 1e18; @@ -72,7 +72,7 @@ contract CurveLibTest is EulerSwapTestBase { uint256 xCalc = CurveLib.fInverse(y, px, py, x0, y0, cx); console.log("xCalc", xCalc); uint256 yCalc = CurveLib.f(xCalc, px, py, x0, y0, cx); - uint256 xBin = CurveLib.binarySearch(p, y, 1, x0); + uint256 xBin = binarySearch(p, y, 1, x0); uint256 yBin = CurveLib.f(xBin, px, py, x0, y0, cx); console.log("x ", x); console.log("xCalc", xCalc); @@ -86,4 +86,32 @@ contract CurveLibTest is EulerSwapTestBase { assert(int256(xCalc) - int256(xBin) <= 3 || int256(yCalc) - int256(yBin) <= 3); // suspect this is 2 wei error in fInverse() + 1 wei error in f() } } + + /// @dev Less efficient method to compute fInverse. Useful for differential fuzzing. + function binarySearch(IEulerSwap.Params memory p, uint256 newReserve1, uint256 xMin, uint256 xMax) + internal + pure + returns (uint256) + { + if (xMin < 1) { + xMin = 1; + } + while (xMin < xMax) { + uint256 xMid = (xMin + xMax) / 2; + uint256 fxMid = + CurveLib.f(xMid, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX); + if (newReserve1 >= fxMid) { + xMax = xMid; + } else { + xMin = xMid + 1; + } + } + if ( + newReserve1 + < CurveLib.f(xMin, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX) + ) { + xMin += 1; + } + return xMin; + } } From 5097bb6878248fd4d3c1915699137824ceff11d2 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Thu, 24 Apr 2025 12:02:49 -0400 Subject: [PATCH 292/312] remove unused y0, clean-up pre-conditions --- src/libraries/CurveExtrasLib.sol | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libraries/CurveExtrasLib.sol b/src/libraries/CurveExtrasLib.sol index 46804c9..9d3933b 100644 --- a/src/libraries/CurveExtrasLib.sol +++ b/src/libraries/CurveExtrasLib.sol @@ -5,12 +5,8 @@ import {Math} from "openzeppelin-contracts/utils/math/Math.sol"; library CurveExtrasLib { /// @dev EulerSwap derivative helper function to find the price after a swap - /// Pre-conditions: 0 < x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 - function df_dx(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) - internal - pure - returns (int256) - { + /// Pre-conditions: 0 < x <= x0 <= type(uint112).max, 1 <= {px,py} <= 1e36, c <= 1e18 + function df_dx(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 c) internal pure returns (int256) { uint256 r = Math.mulDiv(x0 * x0 / x, 1e18, x, Math.Rounding.Ceil); return -int256(px * (c + (1e18 - c) * r / 1e18) / py); } From debf2b73e0df4eb767a96b5b2ae6fb4dc5d4ba65 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Fri, 25 Apr 2025 18:17:10 +0100 Subject: [PATCH 293/312] fix: scale issue in fInverse --- src/libraries/CurveLib.sol | 65 ++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/src/libraries/CurveLib.sol b/src/libraries/CurveLib.sol index dca5a13..7b7e451 100644 --- a/src/libraries/CurveLib.sol +++ b/src/libraries/CurveLib.sol @@ -50,34 +50,30 @@ library CurveLib { int256 B; uint256 C; uint256 fourAC; + unchecked { - B = int256((py * (y - y0) + (px - 1)) / px) - (2 * int256(c) - int256(1e18)) * int256(x0) / 1e18; - if (x0 >= 1e18) { - // if x0 >= 1, scale as normal - C = Math.mulDiv((1e18 - c), x0 * x0, 1e36, Math.Rounding.Ceil); - fourAC = 4 * c * C; - } else { - // if x0 < 1, then numbers get very small, so decrease scale to 1e18 to increase precision later - C = ((1e18 - c) * x0 * x0 + (1e18 - 1)) / 1e18; - fourAC = Math.mulDiv(4 * c, C, 1e18, Math.Rounding.Ceil); - } + int256 term1 = int256(Math.mulDiv(py * 1e18, y - y0, px, Math.Rounding.Ceil)); // scale: 1e36 + int256 term2 = (2 * int256(c) - int256(1e18)) * int256(x0); // scale: 1e36 + B = (term1 - term2) / int256(1e18); // scale: 1e18 + C = Math.mulDiv((1e18 - c), x0 * x0, 1e18, Math.Rounding.Ceil); // scale: 1e36 + fourAC = Math.mulDiv(4 * c, C, 1e18, Math.Rounding.Ceil); // scale: 1e36 } uint256 absB = uint256(B >= 0 ? B : -B); uint256 squaredB; uint256 discriminant; uint256 sqrt; - if (absB < 1e36) { - // safe to use naive squaring + if (absB < 1e36) { + // B^2 can be calculated directly at 1e18 scale without overflowing unchecked { - squaredB = absB * absB; - discriminant = squaredB + fourAC; // keep in 1e36 scale for increased precision ahead of sqrt - sqrt = Math.sqrt(discriminant); // drop back to 1e18 scale + squaredB = absB * absB; // scale: 1e36 + discriminant = squaredB + fourAC; // scale: 1e36 + sqrt = Math.sqrt(discriminant); // // scale: 1e18 sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; } - } else { - // use scaled, overflow-safe path - uint256 scale = computeScale(absB); + } else { + // B^2 cannot be calculated directly at 1e18 scale without overflowing + uint256 scale = computeScale(absB); // calculate the scaling factor such that B^2 can be calculated without overflowing squaredB = Math.mulDiv(absB / scale, absB, scale, Math.Rounding.Ceil); discriminant = squaredB + fourAC / (scale * scale); sqrt = Math.sqrt(discriminant); @@ -87,9 +83,11 @@ library CurveLib { uint256 x; if (B <= 0) { - x = Math.mulDiv(absB + sqrt, 1e18, 2 * c, Math.Rounding.Ceil) + 3; + // use the regular quadratic formula solution (-b + sqrt(b^2 - 4ac)) / 2a + x = Math.mulDiv(absB + sqrt, 1e18, 2 * c, Math.Rounding.Ceil) + 1; } else { - x = Math.mulDiv(2 * C, 1e18, absB + sqrt, Math.Rounding.Ceil) + 3; + // use the "citardauq" quadratic formula solution 2c / (-b + sqrt(b^2 - 4ac)) + x = (2 * C + (absB + sqrt - 1)) / (absB + sqrt) + 1; } if (x >= x0) { @@ -116,4 +114,29 @@ library CurveLib { scale = 1; } } -} + + /// @dev Less efficient method to compute fInverse. Useful for testing. + function binarySearch(IEulerSwap.Params memory p, uint256 newReserve1, uint256 xMin, uint256 xMax) + internal + pure + returns (uint256) + { + if (xMin < 1) { + xMin = 1; + } + while (xMin < xMax) { + uint256 xMid = (xMin + xMax) / 2; + uint256 fxMid = f(xMid, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX); + if (newReserve1 >= fxMid) { + xMax = xMid; + } else { + xMin = xMid + 1; + } + } + if (newReserve1 < f(xMin, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX)) { + xMin += 1; + } + return xMin; + } + +} \ No newline at end of file From 453858eaa76177d1d478371b12c2bbf013d5af27 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 25 Apr 2025 16:14:07 -0400 Subject: [PATCH 294/312] remove binarySearch, since it is now in test dir --- src/libraries/CurveLib.sol | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/libraries/CurveLib.sol b/src/libraries/CurveLib.sol index 7b7e451..2f5df03 100644 --- a/src/libraries/CurveLib.sol +++ b/src/libraries/CurveLib.sol @@ -114,29 +114,4 @@ library CurveLib { scale = 1; } } - - /// @dev Less efficient method to compute fInverse. Useful for testing. - function binarySearch(IEulerSwap.Params memory p, uint256 newReserve1, uint256 xMin, uint256 xMax) - internal - pure - returns (uint256) - { - if (xMin < 1) { - xMin = 1; - } - while (xMin < xMax) { - uint256 xMid = (xMin + xMax) / 2; - uint256 fxMid = f(xMid, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX); - if (newReserve1 >= fxMid) { - xMax = xMid; - } else { - xMin = xMid + 1; - } - } - if (newReserve1 < f(xMin, p.priceX, p.priceY, p.equilibriumReserve0, p.equilibriumReserve1, p.concentrationX)) { - xMin += 1; - } - return xMin; - } - -} \ No newline at end of file +} From be43b1222c0d664a35ff45dc27f24e96dfa6a406 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 25 Apr 2025 16:15:34 -0400 Subject: [PATCH 295/312] move CurveExtrasLib into test/ for now --- docs/architecture.md | 1 - {src/libraries => test/utils}/CurveExtrasLib.sol | 0 2 files changed, 1 deletion(-) rename {src/libraries => test/utils}/CurveExtrasLib.sol (100%) diff --git a/docs/architecture.md b/docs/architecture.md index 6b4fc2a..8aefb20 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -25,7 +25,6 @@ The above contracts depend on libraries: * `FundsLib`: Moving tokens: approvals and transfers in/out * `CurveLib`: Mathematical routines for calculating the EulerSwap curve * `QuoteLib`: Computing quotes. This involves invoking the logic from `CurveLib`, as well as taking into account other limitations such as vault utilisation, supply caps, etc. -* `CurveExtrasLib`: Extra utilities for curve computations. Not used in the EulerSwap itself, but potentially useful for integrators. And some utilities: diff --git a/src/libraries/CurveExtrasLib.sol b/test/utils/CurveExtrasLib.sol similarity index 100% rename from src/libraries/CurveExtrasLib.sol rename to test/utils/CurveExtrasLib.sol From 612bbb1da0cd3c6f56c1d932038a1de6fd289acd Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 25 Apr 2025 16:16:36 -0400 Subject: [PATCH 296/312] forge fmt --- src/libraries/CurveLib.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/CurveLib.sol b/src/libraries/CurveLib.sol index 2f5df03..1cdd820 100644 --- a/src/libraries/CurveLib.sol +++ b/src/libraries/CurveLib.sol @@ -54,7 +54,7 @@ library CurveLib { unchecked { int256 term1 = int256(Math.mulDiv(py * 1e18, y - y0, px, Math.Rounding.Ceil)); // scale: 1e36 int256 term2 = (2 * int256(c) - int256(1e18)) * int256(x0); // scale: 1e36 - B = (term1 - term2) / int256(1e18); // scale: 1e18 + B = (term1 - term2) / int256(1e18); // scale: 1e18 C = Math.mulDiv((1e18 - c), x0 * x0, 1e18, Math.Rounding.Ceil); // scale: 1e36 fourAC = Math.mulDiv(4 * c, C, 1e18, Math.Rounding.Ceil); // scale: 1e36 } @@ -63,7 +63,7 @@ library CurveLib { uint256 squaredB; uint256 discriminant; uint256 sqrt; - if (absB < 1e36) { + if (absB < 1e36) { // B^2 can be calculated directly at 1e18 scale without overflowing unchecked { squaredB = absB * absB; // scale: 1e36 @@ -71,7 +71,7 @@ library CurveLib { sqrt = Math.sqrt(discriminant); // // scale: 1e18 sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; } - } else { + } else { // B^2 cannot be calculated directly at 1e18 scale without overflowing uint256 scale = computeScale(absB); // calculate the scaling factor such that B^2 can be calculated without overflowing squaredB = Math.mulDiv(absB / scale, absB, scale, Math.Rounding.Ceil); From a8cf4966e1357e205b9fe4d16432d8a24b40ad56 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 25 Apr 2025 16:18:14 -0400 Subject: [PATCH 297/312] tighten up MAX_QUOTE_ERROR --- test/EulerSwapTestBase.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index f8ec663..5c149f4 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -13,7 +13,7 @@ import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; import {MetaProxyDeployer} from "../src/utils/MetaProxyDeployer.sol"; contract EulerSwapTestBase is EVaultTestBase { - uint256 public constant MAX_QUOTE_ERROR = 4; + uint256 public constant MAX_QUOTE_ERROR = 2; address public depositor = makeAddr("depositor"); address public holder = makeAddr("holder"); From ec309418da57817374b87979b9a252bb7d5de467 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 28 Apr 2025 14:56:20 -0400 Subject: [PATCH 298/312] test from MiloTruck --- test/FactoryTest.t.sol | 54 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/test/FactoryTest.t.sol b/test/FactoryTest.t.sol index 628cd8c..9aec9bf 100644 --- a/test/FactoryTest.t.sol +++ b/test/FactoryTest.t.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.24; +import {stdError} from "forge-std/Test.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; @@ -247,4 +248,57 @@ contract FactoryTest is EulerSwapTestBase { vm.expectRevert(EulerSwap.Locked.selector); EulerSwap(eulerSwapImpl).getReserves(); } + + + + address alice = makeAddr("alice"); + address bob = makeAddr("bob"); + + function test_multipleUninstalls() public { + // Parameters for deployPool() + IEulerSwap.Params memory params = IEulerSwap.Params({ + vault0: address(eTST), + vault1: address(eTST2), + eulerAccount: address(0), + equilibriumReserve0: 1e18, + equilibriumReserve1: 1e18, + priceX: 1e18, + priceY: 1e18, + concentrationX: 0, + concentrationY: 0, + fee: 0, + protocolFee: 0, + protocolFeeRecipient: address(0) + }); + IEulerSwap.InitialState memory initialState = IEulerSwap.InitialState({ + currReserve0: 1e18, + currReserve1: 1e18 + }); + bytes32 salt = bytes32(0); + + // Deploy pool for Alice + params.eulerAccount = alice; + address alicePool = eulerSwapFactory.computePoolAddress(params, salt); + vm.startPrank(alice); + evc.setAccountOperator(alice, alicePool, true); + eulerSwapFactory.deployPool(params, initialState, salt); + + // Deploy pool for Bob + params.eulerAccount = bob; + address bobPool = eulerSwapFactory.computePoolAddress(params, salt); + vm.startPrank(bob); + evc.setAccountOperator(bob, bobPool, true); + eulerSwapFactory.deployPool(params, initialState, salt); + + // Uninstall pool for Alice + vm.startPrank(alice); + evc.setAccountOperator(alice, alicePool, false); + eulerSwapFactory.uninstallPool(); + + // Uninstalling pool for Bob reverts due to an OOB access of the allPools array + vm.startPrank(bob); + evc.setAccountOperator(bob, bobPool, false); + vm.expectRevert(stdError.indexOOBError); + eulerSwapFactory.uninstallPool(); + } } From d568fa0971b027b26ccef0ecf9e43132ec80f224 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 28 Apr 2025 15:24:18 -0400 Subject: [PATCH 299/312] integrate and expand test --- test/FactoryTest.t.sol | 78 ++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/test/FactoryTest.t.sol b/test/FactoryTest.t.sol index 9aec9bf..47658bd 100644 --- a/test/FactoryTest.t.sol +++ b/test/FactoryTest.t.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.24; -import {stdError} from "forge-std/Test.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {PoolManagerDeployer} from "./utils/PoolManagerDeployer.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; @@ -249,56 +248,75 @@ contract FactoryTest is EulerSwapTestBase { EulerSwap(eulerSwapImpl).getReserves(); } - - address alice = makeAddr("alice"); address bob = makeAddr("bob"); function test_multipleUninstalls() public { - // Parameters for deployPool() - IEulerSwap.Params memory params = IEulerSwap.Params({ - vault0: address(eTST), - vault1: address(eTST2), - eulerAccount: address(0), - equilibriumReserve0: 1e18, - equilibriumReserve1: 1e18, - priceX: 1e18, - priceY: 1e18, - concentrationX: 0, - concentrationY: 0, - fee: 0, - protocolFee: 0, - protocolFeeRecipient: address(0) - }); - IEulerSwap.InitialState memory initialState = IEulerSwap.InitialState({ - currReserve0: 1e18, - currReserve1: 1e18 - }); - bytes32 salt = bytes32(0); + (IEulerSwap.Params memory params, IEulerSwap.InitialState memory initialState) = getBasicParams(); // Deploy pool for Alice - params.eulerAccount = alice; - address alicePool = eulerSwapFactory.computePoolAddress(params, salt); + params.eulerAccount = holder = alice; + (address alicePool, bytes32 aliceSalt) = mineSalt(params); + vm.startPrank(alice); evc.setAccountOperator(alice, alicePool, true); - eulerSwapFactory.deployPool(params, initialState, salt); + eulerSwapFactory.deployPool(params, initialState, aliceSalt); // Deploy pool for Bob - params.eulerAccount = bob; - address bobPool = eulerSwapFactory.computePoolAddress(params, salt); + params.eulerAccount = holder = bob; + (address bobPool, bytes32 bobSalt) = mineSalt(params); + vm.startPrank(bob); evc.setAccountOperator(bob, bobPool, true); - eulerSwapFactory.deployPool(params, initialState, salt); + eulerSwapFactory.deployPool(params, initialState, bobSalt); + + { + address[] memory ps = eulerSwapFactory.pools(); + assertEq(ps.length, 2); + assertEq(ps[0], alicePool); + assertEq(ps[1], bobPool); + } + + { + (address asset0, address asset1) = EulerSwap(alicePool).getAssets(); + address[] memory ps = eulerSwapFactory.poolsByPair(asset0, asset1); + assertEq(ps.length, 2); + assertEq(ps[0], alicePool); + assertEq(ps[1], bobPool); + } // Uninstall pool for Alice vm.startPrank(alice); evc.setAccountOperator(alice, alicePool, false); eulerSwapFactory.uninstallPool(); + { + address[] memory ps = eulerSwapFactory.pools(); + assertEq(ps.length, 1); + assertEq(ps[0], bobPool); + } + + { + (address asset0, address asset1) = EulerSwap(alicePool).getAssets(); + address[] memory ps = eulerSwapFactory.poolsByPair(asset0, asset1); + assertEq(ps.length, 1); + assertEq(ps[0], bobPool); + } + // Uninstalling pool for Bob reverts due to an OOB access of the allPools array vm.startPrank(bob); evc.setAccountOperator(bob, bobPool, false); - vm.expectRevert(stdError.indexOOBError); eulerSwapFactory.uninstallPool(); + + { + address[] memory ps = eulerSwapFactory.pools(); + assertEq(ps.length, 0); + } + + { + (address asset0, address asset1) = EulerSwap(alicePool).getAssets(); + address[] memory ps = eulerSwapFactory.poolsByPair(asset0, asset1); + assertEq(ps.length, 0); + } } } From 36350925bd78432c3123bc94af2e36785a0d80df Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 28 Apr 2025 15:35:10 -0400 Subject: [PATCH 300/312] fix issue with multiple uninstalls by using OZ's EnumerableSet library --- src/EulerSwapFactory.sol | 62 +++++++++++++--------------- src/interfaces/IEulerSwapFactory.sol | 6 --- 2 files changed, 28 insertions(+), 40 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index c115ec0..08ed404 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; +import {EnumerableSet} from "openzeppelin-contracts/utils/structs/EnumerableSet.sol"; + import {IEulerSwapFactory, IEulerSwap} from "./interfaces/IEulerSwapFactory.sol"; import {EVCUtil} from "ethereum-vault-connector/utils/EVCUtil.sol"; import {GenericFactory} from "evk/GenericFactory/GenericFactory.sol"; @@ -13,15 +15,19 @@ import {MetaProxyDeployer} from "./utils/MetaProxyDeployer.sol"; /// @custom:security-contact security@euler.xyz /// @author Euler Labs (https://www.eulerlabs.com/) contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { - /// @dev An array to store all pools addresses. - address[] private allPools; + using EnumerableSet for EnumerableSet.AddressSet; + /// @dev Vaults must be deployed by this factory address public immutable evkFactory; /// @dev The EulerSwap code instance that will be proxied to address public immutable eulerSwapImpl; - /// @dev Mapping between euler account and EulerAccountState - mapping(address eulerAccount => EulerAccountState state) private eulerAccountState; - mapping(address asset0 => mapping(address asset1 => address[])) private poolMap; + + /// @dev Mapping from euler account to pool, if installed + mapping(address eulerAccount => address) internal installedPools; + /// @dev Set of all pool addresses + EnumerableSet.AddressSet internal allPools; + /// @dev Mapping from sorted pair of underlyings to set of pools + mapping(address asset0 => mapping(address asset1 => EnumerableSet.AddressSet)) internal poolMap; event PoolDeployed(address indexed asset0, address indexed asset1, address indexed eulerAccount, address pool); event PoolConfig(address indexed pool, IEulerSwap.Params params, IEulerSwap.InitialState initialState); @@ -102,12 +108,12 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { /// @inheritdoc IEulerSwapFactory function poolByEulerAccount(address eulerAccount) external view returns (address) { - return eulerAccountState[eulerAccount].pool; + return installedPools[eulerAccount]; } /// @inheritdoc IEulerSwapFactory function poolsLength() external view returns (uint256) { - return allPools.length; + return allPools.length(); } /// @inheritdoc IEulerSwapFactory @@ -122,7 +128,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { /// @inheritdoc IEulerSwapFactory function poolsByPairLength(address asset0, address asset1) external view returns (uint256) { - return poolMap[asset0][asset1].length; + return poolMap[asset0][asset1].length(); } /// @inheritdoc IEulerSwapFactory @@ -147,16 +153,10 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { (address asset0, address asset1) = _getAssets(newOperator); - address[] storage poolMapArray = poolMap[asset0][asset1]; + installedPools[eulerAccount] = newOperator; - eulerAccountState[eulerAccount] = EulerAccountState({ - pool: newOperator, - allPoolsIndex: uint48(allPools.length), - poolMapIndex: uint48(poolMapArray.length) - }); - - allPools.push(newOperator); - poolMapArray.push(newOperator); + allPools.add(newOperator); + poolMap[asset0][asset1].add(newOperator); } /// @notice Uninstalls the pool associated with the given Euler account @@ -165,7 +165,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { /// @dev If no pool exists for the account, the function returns without any action /// @param eulerAccount The address of the Euler account whose pool should be uninstalled function uninstall(address eulerAccount) internal { - address pool = eulerAccountState[eulerAccount].pool; + address pool = installedPools[eulerAccount]; if (pool == address(0)) return; @@ -173,24 +173,14 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { (address asset0, address asset1) = _getAssets(pool); - address[] storage poolMapArr = poolMap[asset0][asset1]; - - swapAndPop(allPools, eulerAccountState[eulerAccount].allPoolsIndex); - swapAndPop(poolMapArr, eulerAccountState[eulerAccount].poolMapIndex); + allPools.remove(pool); + poolMap[asset0][asset1].remove(pool); - delete eulerAccountState[eulerAccount]; + delete installedPools[eulerAccount]; emit PoolUninstalled(asset0, asset1, eulerAccount, pool); } - /// @notice Swaps the element at the given index with the last element and removes the last element - /// @param arr The storage array to modify - /// @param index The index of the element to remove - function swapAndPop(address[] storage arr, uint256 index) internal { - arr[index] = arr[arr.length - 1]; - arr.pop(); - } - /// @notice Retrieves the asset addresses for a given pool /// @dev Calls the pool contract to get its asset0 and asset1 addresses /// @param pool The address of the pool to query @@ -206,14 +196,18 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { /// @param start The starting index of the slice (inclusive) /// @param end The ending index of the slice (exclusive) /// @return A new memory array containing the requested slice of addresses - function _getSlice(address[] storage arr, uint256 start, uint256 end) internal view returns (address[] memory) { - uint256 length = arr.length; + function _getSlice(EnumerableSet.AddressSet storage arr, uint256 start, uint256 end) + internal + view + returns (address[] memory) + { + uint256 length = arr.length(); if (end == type(uint256).max) end = length; if (end < start || end > length) revert SliceOutOfBounds(); address[] memory slice = new address[](end - start); for (uint256 i; i < end - start; ++i) { - slice[i] = arr[start + i]; + slice[i] = arr.at(start + i); } return slice; diff --git a/src/interfaces/IEulerSwapFactory.sol b/src/interfaces/IEulerSwapFactory.sol index d20c391..bdd4c34 100644 --- a/src/interfaces/IEulerSwapFactory.sol +++ b/src/interfaces/IEulerSwapFactory.sol @@ -4,12 +4,6 @@ pragma solidity >=0.8.0; import {IEulerSwap} from "./IEulerSwap.sol"; interface IEulerSwapFactory { - struct EulerAccountState { - address pool; - uint48 allPoolsIndex; - uint48 poolMapIndex; - } - /// @notice Deploy a new EulerSwap pool with the given parameters /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from /// the euler account address and provided salt parameter. This allows the pool address to be From fc9a1ad1730189dc22db0fa29cb47d6762b8cd72 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 28 Apr 2025 17:04:48 -0400 Subject: [PATCH 301/312] test for UnsupportedPair errors --- test/Basic.t.sol | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/Basic.t.sol b/test/Basic.t.sol index c208f5e..75b5cf5 100644 --- a/test/Basic.t.sol +++ b/test/Basic.t.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.24; import {IEVault, IEulerSwap, EulerSwapTestBase, EulerSwap, TestERC20} from "./EulerSwapTestBase.t.sol"; +import {QuoteLib} from "../src/libraries/QuoteLib.sol"; contract Basic is EulerSwapTestBase { EulerSwap public eulerSwap; @@ -40,6 +41,14 @@ contract Basic is EulerSwapTestBase { assertEq(assetTST2.balanceOf(address(this)), amountOut); } + function test_badTokenAddrs() public { + vm.expectRevert(QuoteLib.UnsupportedPair.selector); + periphery.quoteExactInput(address(eulerSwap), address(assetTST), address(1234), 0); + + vm.expectRevert(QuoteLib.UnsupportedPair.selector); + periphery.quoteExactInput(address(eulerSwap), address(1234), address(assetTST), 0); + } + function test_altPrice() public { uint256 price = 0.5e18; uint256 px = price; From 644ff6d6a897988d038a728d0559777f19ba1a02 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 28 Apr 2025 18:04:05 -0400 Subject: [PATCH 302/312] fix parameter ordering bug resulting in incorrect quotes --- src/libraries/QuoteLib.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/QuoteLib.sol b/src/libraries/QuoteLib.sol index 6be7779..465d4a4 100644 --- a/src/libraries/QuoteLib.sol +++ b/src/libraries/QuoteLib.sol @@ -210,7 +210,7 @@ library QuoteLib { xNew = reserve0 - amount; if (xNew < x0) { // remain on f() - yNew = CurveLib.f(xNew, py, px, y0, x0, cx); + yNew = CurveLib.f(xNew, px, py, x0, y0, cx); } else { // move to g() yNew = CurveLib.fInverse(xNew, py, px, y0, x0, cy); From c514e815902ad2a3b946b7a1729ccbee9490e1c8 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 28 Apr 2025 18:04:30 -0400 Subject: [PATCH 303/312] in fuzz tests, exercise quoteExactOutput() code path --- test/Basic.t.sol | 8 ++++++++ test/PreserveNav.t.sol | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/test/Basic.t.sol b/test/Basic.t.sol index c208f5e..4f02aeb 100644 --- a/test/Basic.t.sol +++ b/test/Basic.t.sol @@ -114,6 +114,10 @@ contract Basic is EulerSwapTestBase { t1.mint(address(this), amount); uint256 q = periphery.quoteExactInput(address(eulerSwap), address(t1), address(t2), amount); + { + uint256 qRev = periphery.quoteExactOutput(address(eulerSwap), address(t1), address(t2), q); + assertApproxEqAbs(amount, qRev, 200 + (MAX_QUOTE_ERROR + 1) * 2); // max 100:1 price differential, 2 swaps + } t1.transfer(address(eulerSwap), amount); if (dir) eulerSwap.swap(0, q, address(this), ""); @@ -122,6 +126,10 @@ contract Basic is EulerSwapTestBase { t2.mint(address(this), amount2); uint256 q2 = periphery.quoteExactInput(address(eulerSwap), address(t2), address(t1), amount2); + { + uint256 qRev = periphery.quoteExactOutput(address(eulerSwap), address(t2), address(t1), q2); + assertApproxEqAbs(amount2, qRev, 200 + (MAX_QUOTE_ERROR + 1) * 2); + } t2.transfer(address(eulerSwap), amount2); if (dir) eulerSwap.swap(q2, 0, address(this), ""); diff --git a/test/PreserveNav.t.sol b/test/PreserveNav.t.sol index 1043804..a20d312 100644 --- a/test/PreserveNav.t.sol +++ b/test/PreserveNav.t.sol @@ -42,6 +42,10 @@ contract PreserveNav is EulerSwapTestBase { else (t1, t2) = (assetTST2, assetTST); uint256 q = periphery.quoteExactInput(address(eulerSwap), address(t1), address(t2), amount1); + { + uint256 qRev = periphery.quoteExactOutput(address(eulerSwap), address(t1), address(t2), q); + assertApproxEqAbs(amount1, qRev, (MAX_QUOTE_ERROR + 1) * 2); + } t1.mint(address(this), amount1); t1.transfer(address(eulerSwap), amount1); @@ -66,6 +70,10 @@ contract PreserveNav is EulerSwapTestBase { else (t1, t2) = (assetTST2, assetTST); uint256 q = periphery.quoteExactInput(address(eulerSwap), address(t1), address(t2), amount2); + { + uint256 qRev = periphery.quoteExactOutput(address(eulerSwap), address(t1), address(t2), q); + assertApproxEqAbs(amount2, qRev, (MAX_QUOTE_ERROR + 1) * 2); + } t1.mint(address(this), amount2); t1.transfer(address(eulerSwap), amount2); From ed485c3159087f7fa377be3668eb417ce2e33076 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 28 Apr 2025 18:31:25 -0400 Subject: [PATCH 304/312] test for getHookPermissions --- test/HookSwaps.t.sol | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/HookSwaps.t.sol b/test/HookSwaps.t.sol index 0eac841..ad28c4f 100644 --- a/test/HookSwaps.t.sol +++ b/test/HookSwaps.t.sol @@ -126,6 +126,26 @@ contract HookSwapsTest is EulerSwapTestBase { vm.stopPrank(); } + function test_hookPermissions() public view { + Hooks.Permissions memory perms = eulerSwap.getHookPermissions(); + + assertTrue(perms.beforeInitialize); + assertTrue(perms.beforeAddLiquidity); + assertTrue(perms.beforeSwap); + assertTrue(perms.beforeSwapReturnDelta); + + assertFalse(perms.afterInitialize); + assertFalse(perms.afterAddLiquidity); + assertFalse(perms.beforeRemoveLiquidity); + assertFalse(perms.afterRemoveLiquidity); + assertFalse(perms.afterSwap); + assertFalse(perms.beforeDonate); + assertFalse(perms.afterDonate); + assertFalse(perms.afterSwapReturnDelta); + assertFalse(perms.afterAddLiquidityReturnDelta); + assertFalse(perms.afterRemoveLiquidityReturnDelta); + } + /// @dev adding liquidity as a concentrated liquidity position will revert function test_revertAddConcentratedLiquidity() public { assetTST.mint(anyone, 10000e18); From 533934ee2cc4c6444c58bca6cfce3ab688663e7e Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Mon, 28 Apr 2025 23:54:19 -0400 Subject: [PATCH 305/312] avoid use of assembly in getParams (suggested by @MiloTruck) --- src/libraries/CtxLib.sol | 19 ++++++------------- test/Ctx.t.sol | 30 +++++++++++++++++++++++++++++- test/FactoryTest.t.sol | 10 ---------- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/libraries/CtxLib.sol b/src/libraries/CtxLib.sol index 8649a3d..ed11e77 100644 --- a/src/libraries/CtxLib.sol +++ b/src/libraries/CtxLib.sol @@ -19,22 +19,15 @@ library CtxLib { } } + error InsufficientCalldata(); + /// @dev Unpacks encoded Params from trailing calldata. Loosely based on /// the implementation from EIP-3448 (except length is hard-coded). + /// 384 is the size of the Params struct after ABI encoding. function getParams() internal pure returns (IEulerSwap.Params memory p) { - bytes memory data; - - assembly { - let size := 384 - let dataPtr := sub(calldatasize(), size) - data := mload(64) - // increment free memory pointer by metadata size + 32 bytes (length) - mstore(64, add(data, add(size, 32))) - mstore(data, size) - let memPtr := add(data, 32) - calldatacopy(memPtr, dataPtr, size) + require(msg.data.length >= 384, InsufficientCalldata()); + unchecked { + return abi.decode(msg.data[msg.data.length - 384:], (IEulerSwap.Params)); } - - return abi.decode(data, (IEulerSwap.Params)); } } diff --git a/test/Ctx.t.sol b/test/Ctx.t.sol index 5f2d87d..5bcb3af 100644 --- a/test/Ctx.t.sol +++ b/test/Ctx.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.24; -import {EulerSwapTestBase, IEulerSwap} from "./EulerSwapTestBase.t.sol"; +import {EulerSwapTestBase, EulerSwap, IEulerSwap} from "./EulerSwapTestBase.t.sol"; import {CtxLib} from "../src/libraries/CtxLib.sol"; contract CtxTest is EulerSwapTestBase { @@ -17,4 +17,32 @@ contract CtxTest is EulerSwapTestBase { IEulerSwap.Params memory params = getEulerSwapParams(1e18, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 0, 0, address(0)); assertEq(abi.encode(params).length, 384); } + + function test_insufficientCalldata() public { + // Proxy appends 384 bytes of calldata, so you can't call directly without this + + vm.expectRevert(CtxLib.InsufficientCalldata.selector); + EulerSwap(eulerSwapImpl).getParams(); + } + + function test_callImplementationDirectly() public { + // Underlying implementation is locked: must call via a proxy + + bool success; + + vm.expectRevert(EulerSwap.AlreadyActivated.selector); + (success,) = eulerSwapImpl.call( + padCalldata( + abi.encodeCall(EulerSwap.activate, (IEulerSwap.InitialState({currReserve0: 1e18, currReserve1: 1e18}))) + ) + ); + + vm.expectRevert(EulerSwap.Locked.selector); + (success,) = eulerSwapImpl.call(padCalldata(abi.encodeCall(EulerSwap.getReserves, ()))); + } + + function padCalldata(bytes memory inp) internal pure returns (bytes memory) { + IEulerSwap.Params memory params; + return abi.encodePacked(inp, abi.encode(params)); + } } diff --git a/test/FactoryTest.t.sol b/test/FactoryTest.t.sol index 628cd8c..a18746b 100644 --- a/test/FactoryTest.t.sol +++ b/test/FactoryTest.t.sol @@ -237,14 +237,4 @@ contract FactoryTest is EulerSwapTestBase { assertEq(pools.length, 1); assertEq(pools[0], hookAddress); } - - function testCallImpl() public { - // Underlying implementation is locked: must call via a proxy - - vm.expectRevert(EulerSwap.AlreadyActivated.selector); - EulerSwap(eulerSwapImpl).activate(IEulerSwap.InitialState({currReserve0: 1e18, currReserve1: 1e18})); - - vm.expectRevert(EulerSwap.Locked.selector); - EulerSwap(eulerSwapImpl).getReserves(); - } } From 6b1bdf264d1b8453ed53dc75be47cabc05a34e9f Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 29 Apr 2025 00:23:56 -0400 Subject: [PATCH 306/312] cosmetic fixes identified in audit --- src/EulerSwap.sol | 2 +- src/EulerSwapFactory.sol | 2 +- src/libraries/CurveLib.sol | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 8d0a857..8df1e56 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -58,7 +58,7 @@ contract EulerSwap is IEulerSwap, EVCUtil, UniswapHook { } /// @inheritdoc IEulerSwap - function activate(InitialState calldata initialState) public { + function activate(InitialState calldata initialState) external { CtxLib.Storage storage s = CtxLib.getStorage(); Params memory p = CtxLib.getParams(); diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index c115ec0..0cec8fb 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -91,7 +91,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { abi.encodePacked( bytes1(0xff), address(this), - keccak256(abi.encode(address(poolParams.eulerAccount), salt)), + keccak256(abi.encode(poolParams.eulerAccount, salt)), keccak256(MetaProxyDeployer.creationCodeMetaProxy(eulerSwapImpl, abi.encode(poolParams))) ) ) diff --git a/src/libraries/CurveLib.sol b/src/libraries/CurveLib.sol index 1cdd820..f818d50 100644 --- a/src/libraries/CurveLib.sol +++ b/src/libraries/CurveLib.sol @@ -9,7 +9,7 @@ library CurveLib { error Overflow(); error CurveViolation(); - /// @notice Returns true iff the specified reserve amounts would be acceptable. + /// @notice Returns true if the specified reserve amounts would be acceptable, false otherwise. /// Acceptable points are on, or above and to-the-right of the swapping curve. function verify(IEulerSwap.Params memory p, uint256 newReserve0, uint256 newReserve1) internal @@ -55,7 +55,7 @@ library CurveLib { int256 term1 = int256(Math.mulDiv(py * 1e18, y - y0, px, Math.Rounding.Ceil)); // scale: 1e36 int256 term2 = (2 * int256(c) - int256(1e18)) * int256(x0); // scale: 1e36 B = (term1 - term2) / int256(1e18); // scale: 1e18 - C = Math.mulDiv((1e18 - c), x0 * x0, 1e18, Math.Rounding.Ceil); // scale: 1e36 + C = Math.mulDiv(1e18 - c, x0 * x0, 1e18, Math.Rounding.Ceil); // scale: 1e36 fourAC = Math.mulDiv(4 * c, C, 1e18, Math.Rounding.Ceil); // scale: 1e36 } @@ -68,7 +68,7 @@ library CurveLib { unchecked { squaredB = absB * absB; // scale: 1e36 discriminant = squaredB + fourAC; // scale: 1e36 - sqrt = Math.sqrt(discriminant); // // scale: 1e18 + sqrt = Math.sqrt(discriminant); // scale: 1e18 sqrt = (sqrt * sqrt < discriminant) ? sqrt + 1 : sqrt; } } else { From 59a0f83db7671551b323d7479da8d99bc0f90130 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 29 Apr 2025 00:53:42 -0400 Subject: [PATCH 307/312] combining eulerAccount with salt is no longer necessary --- src/EulerSwapFactory.sol | 4 ++-- test/FactoryTest.t.sol | 12 ++++++++++++ test/utils/HookMiner.sol | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 0cec8fb..5a97309 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -62,7 +62,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { EulerSwap pool = EulerSwap( MetaProxyDeployer.deployMetaProxy( - eulerSwapImpl, abi.encode(params), keccak256(abi.encode(params.eulerAccount, salt)) + eulerSwapImpl, abi.encode(params), salt ) ); @@ -91,7 +91,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { abi.encodePacked( bytes1(0xff), address(this), - keccak256(abi.encode(poolParams.eulerAccount, salt)), + salt, keccak256(MetaProxyDeployer.creationCodeMetaProxy(eulerSwapImpl, abi.encode(poolParams))) ) ) diff --git a/test/FactoryTest.t.sol b/test/FactoryTest.t.sol index 628cd8c..1ef4ee2 100644 --- a/test/FactoryTest.t.sol +++ b/test/FactoryTest.t.sol @@ -53,6 +53,18 @@ contract FactoryTest is EulerSwapTestBase { (hookAddress, salt) = HookMiner.find(address(eulerSwapFactory), holder, flags, creationCode); } + function testDifferingAddressesSameSalt() public view { + (IEulerSwap.Params memory poolParams,) = getBasicParams(); + + address a1 = eulerSwapFactory.computePoolAddress(poolParams, bytes32(0)); + + poolParams.eulerAccount = address(123); + + address a2 = eulerSwapFactory.computePoolAddress(poolParams, bytes32(0)); + + assert(a1 != a2); + } + function testDeployPool() public { uint256 allPoolsLengthBefore = eulerSwapFactory.poolsLength(); diff --git a/test/utils/HookMiner.sol b/test/utils/HookMiner.sol index 0bcdf88..6f44774 100644 --- a/test/utils/HookMiner.sol +++ b/test/utils/HookMiner.sol @@ -53,7 +53,7 @@ library HookMiner { uint256( keccak256( abi.encodePacked( - bytes1(0xFF), deployer, keccak256(abi.encode(account, salt)), keccak256(creationCode) + bytes1(0xFF), deployer, salt, keccak256(creationCode) ) ) ) From 1e0402d2717b68588089014133ac08c78b065cdc Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 29 Apr 2025 00:55:22 -0400 Subject: [PATCH 308/312] forge fmt --- src/EulerSwapFactory.sol | 6 +----- test/utils/HookMiner.sol | 10 +--------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 5a97309..c427819 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -60,11 +60,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { uninstall(params.eulerAccount); - EulerSwap pool = EulerSwap( - MetaProxyDeployer.deployMetaProxy( - eulerSwapImpl, abi.encode(params), salt - ) - ); + EulerSwap pool = EulerSwap(MetaProxyDeployer.deployMetaProxy(eulerSwapImpl, abi.encode(params), salt)); updateEulerAccountState(params.eulerAccount, address(pool)); diff --git a/test/utils/HookMiner.sol b/test/utils/HookMiner.sol index 6f44774..1b28a84 100644 --- a/test/utils/HookMiner.sol +++ b/test/utils/HookMiner.sol @@ -49,15 +49,7 @@ library HookMiner { returns (address hookAddress) { return address( - uint160( - uint256( - keccak256( - abi.encodePacked( - bytes1(0xFF), deployer, salt, keccak256(creationCode) - ) - ) - ) - ) + uint160(uint256(keccak256(abi.encodePacked(bytes1(0xFF), deployer, salt, keccak256(creationCode))))) ); } } From 53271cbdafb6f4b89f140f1e09aaf763b87b1970 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Tue, 29 Apr 2025 14:42:01 +0100 Subject: [PATCH 309/312] fix: add even stricter checks in fInverse() fuzz test --- test/CurveLib.t.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/CurveLib.t.sol b/test/CurveLib.t.sol index 50d5178..baaf864 100644 --- a/test/CurveLib.t.sol +++ b/test/CurveLib.t.sol @@ -37,7 +37,7 @@ contract CurveLibTest is EulerSwapTestBase { // Params px = 1e18; py = bound(py, 1, 1e36); - x0 = bound(x0, 1e2, 1e28); + x0 = bound(x0, 1, 1e28); y0 = bound(y0, 0, 1e28); cx = bound(cx, 1, 1e18); cy = bound(cy, 1, 1e18); @@ -63,9 +63,7 @@ contract CurveLibTest is EulerSwapTestBase { protocolFeeRecipient: address(0) }); - // Note without -2 in the max bound, f() sometimes fails when x gets too close to centre. - // Note small x values lead to large y-values, which causes problems for both f() and fInverse(), so we cap it here - x = bound(x, 1e2 - 3, x0 - 3); + x = bound(x, 1, x0); uint256 y = CurveLib.f(x, px, py, x0, y0, cx); console.log("y ", y); @@ -83,7 +81,9 @@ contract CurveLibTest is EulerSwapTestBase { if (x < type(uint112).max && y < type(uint112).max) { assert(CurveLib.verify(p, xCalc, y)); - assert(int256(xCalc) - int256(xBin) <= 3 || int256(yCalc) - int256(yBin) <= 3); // suspect this is 2 wei error in fInverse() + 1 wei error in f() + console.log("Invariant passed"); + assert(xCalc - xBin <= 3 || y - yCalc <= 3); // suspect this is 2 wei error in fInverse() + 1 wei error in f() + console.log("Margin error passed"); } } From 3d924ebb532b9928c6f803ea98aa577249d638dc Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 29 Apr 2025 10:44:08 -0400 Subject: [PATCH 310/312] use safeTransfer when moving protocol fees, for non-compliant tokens --- src/libraries/FundsLib.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/FundsLib.sol b/src/libraries/FundsLib.sol index 8241501..91f9073 100644 --- a/src/libraries/FundsLib.sol +++ b/src/libraries/FundsLib.sol @@ -79,7 +79,7 @@ library FundsLib { uint256 protocolFeeAmount = feeAmount * p.protocolFee / 1e18; if (protocolFeeAmount != 0) { - IERC20(asset).transfer(p.protocolFeeRecipient, protocolFeeAmount); + IERC20(asset).safeTransfer(p.protocolFeeRecipient, protocolFeeAmount); amount -= protocolFeeAmount; feeAmount -= protocolFeeAmount; } From c751556a304f8fe6f2ed9d5c7849a2cbcfe28d9e Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 29 Apr 2025 14:36:42 -0400 Subject: [PATCH 311/312] use values() method of EnumerableSet when possible, to make the code simpler --- src/EulerSwapFactory.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 6dd25c7..00cfbb5 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -119,7 +119,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { /// @inheritdoc IEulerSwapFactory function pools() external view returns (address[] memory) { - return _getSlice(allPools, 0, type(uint256).max); + return allPools.values(); } /// @inheritdoc IEulerSwapFactory @@ -138,7 +138,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil, ProtocolFee { /// @inheritdoc IEulerSwapFactory function poolsByPair(address asset0, address asset1) external view returns (address[] memory) { - return _getSlice(poolMap[asset0][asset1], 0, type(uint256).max); + return poolMap[asset0][asset1].values(); } /// @notice Validates operator authorization for euler account and update the relevant EulerAccountState. From 605201e80b080ce7ff81e04bd0e5f549b1f4a880 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Tue, 29 Apr 2025 15:46:40 -0400 Subject: [PATCH 312/312] Constructor sanity check prevented creation of fully one-sided curves (pointed out by @MiloTruck) --- src/EulerSwap.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 8df1e56..af3534b 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -85,8 +85,8 @@ contract EulerSwap is IEulerSwap, EVCUtil, UniswapHook { s.reserve1 = initialState.currReserve1; require(CurveLib.verify(p, s.reserve0, s.reserve1), CurveLib.CurveViolation()); - require(!CurveLib.verify(p, s.reserve0 > 0 ? s.reserve0 - 1 : 0, s.reserve1), CurveLib.CurveViolation()); - require(!CurveLib.verify(p, s.reserve0, s.reserve1 > 0 ? s.reserve1 - 1 : 0), CurveLib.CurveViolation()); + if (s.reserve0 != 0) require(!CurveLib.verify(p, s.reserve0 - 1, s.reserve1), CurveLib.CurveViolation()); + if (s.reserve1 != 0) require(!CurveLib.verify(p, s.reserve0, s.reserve1 - 1), CurveLib.CurveViolation()); // Configure external contracts

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 BSl$2t literal 0 HcmV?d00001 diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts index a3a6db8..acd4ff7 160000 --- a/lib/openzeppelin-contracts +++ b/lib/openzeppelin-contracts @@ -1 +1 @@ -Subproject commit a3a6db86d5b4d7ef003b6f71e6504867d2679a7f +Subproject commit acd4ff74de833399287ed6b31b4debf6b2b35527 From d33b6d8d4b8a893029f74deaf451d13bfeb90dc9 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Fri, 28 Feb 2025 07:30:09 -0500 Subject: [PATCH 154/312] use unchecked math in f() function to improve on-chain quoting efficiency --- docs/f.md | 12 ++++++++++++ src/EulerSwap.sol | 16 ++++++++++++---- test/EulerSwapFactoryTest.t.sol | 2 +- test/EulerSwapTest.t.sol | 5 ++++- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/docs/f.md b/docs/f.md index 54b482b..2ccc23e 100644 --- a/docs/f.md +++ b/docs/f.md @@ -46,3 +46,15 @@ None of the computations for the arguments to `mulDiv` can overflow: If amounts/prices are large, and we travel too far down the curve, then `mulDiv` (or the subsequent `y0` addition) could overflow because its output value cannot be represented as a `uint256`. However, these output values would never be valid anyway, because they exceed `type(uint112).max`. To see this, consider the case where `mulDiv` fails due to overflow. This means that its result would've been greater than `2**256 - 1`. Dividing this value by the largest allowed value for `py` (`1e36`) gives approximately `2**136`, which is greater than the maximum allowed amount value of `2**112 - 1`. Both the rounding up operation and the final addition of `y0` can only further *increase* this value. This means that all cases where `mulDiv` or the subsequent additions overflow would involve `f()` returning values that are impossible for a swapper to satisfy, so they would revert anyways. + +### Unchecked Math + +As-per the previous section, none of the computations of the arguments to `mulDiv` can overflow. To prevent overflows in the remaining operations, the `mulDiv` output is further restricted to `2**248 - 1`: + + unchecked { + uint256 v = Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil); + require(v <= type(uint248).max, Overflow()); + return y0 + (v + (py - 1)) / py; + } + +Note that this does not change the analysis of the previous section: Values between `2**248 - 1` and `2**256 - 1` will also never reduce down to the required `2**112 - 1`, so this does not cause any additional failure cases. diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 040c2e4..9c0c3e2 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -47,7 +47,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { error Locked(); error Overflow(); - error BadFee(); + error BadParam(); error DifferentEVC(); error AssetsOutOfOrderOrEqual(); error CurveViolation(); @@ -64,7 +64,11 @@ contract EulerSwap is IEulerSwap, EVCUtil { constructor(Params memory params, CurveParams memory curveParams) EVCUtil(IEVault(params.vault0).EVC()) { // EulerSwap params - require(params.fee < 1e18, BadFee()); + require(params.fee < 1e18, BadParam()); + require(params.debtLimit0 <= type(uint112).max && params.debtLimit1 <= type(uint112).max, BadParam()); + require(curveParams.priceX > 0 && curveParams.priceY > 0, BadParam()); + require(curveParams.priceX <= 1e36 && curveParams.priceY <= 1e36, BadParam()); + require(curveParams.concentrationX <= 1e18 && curveParams.concentrationY <= 1e18, BadParam()); require(IEVault(params.vault0).EVC() == IEVault(params.vault1).EVC(), DifferentEVC()); address asset0Addr = IEVault(params.vault0).asset(); @@ -240,7 +244,11 @@ contract EulerSwap is IEulerSwap, EVCUtil { /// @dev EulerSwap curve definition /// Pre-conditions: x <= x0, 1 <= {px,py} <= 1e36, {x0,y0} <= type(uint112).max, c <= 1e18 - function f(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) public pure returns (uint256) { - return y0 + (Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil) + (py - 1)) / py; + function f(uint256 x, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) internal pure returns (uint256) { + unchecked { + uint256 v = Math.mulDiv(px * (x0 - x), c * x + (1e18 - c) * x0, x * 1e18, Math.Rounding.Ceil); + require(v <= type(uint248).max, Overflow()); + return y0 + (v + (py - 1)) / py; + } } } diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index bdcff08..ac31089 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -79,7 +79,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { function testDeployWithBadFee() public { vm.prank(creator); - vm.expectRevert(EulerSwap.BadFee.selector); + vm.expectRevert(EulerSwap.BadParam.selector); eulerSwapFactory.deployPool( IEulerSwapFactory.DeployParams( address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18, 0.4e18, 0.85e18, 50e18, 50e18 diff --git a/test/EulerSwapTest.t.sol b/test/EulerSwapTest.t.sol index e80a509..e08ae1b 100644 --- a/test/EulerSwapTest.t.sol +++ b/test/EulerSwapTest.t.sol @@ -176,14 +176,17 @@ contract EulerSwapTest is EulerSwapTestBase { } } + /* + // Make `f()` function public to run this test function test_fFuncOverflow(uint256 xt, uint256 px, uint256 py, uint256 x0, uint256 y0, uint256 c) public view { x0 = bound(x0, 1, type(uint112).max); y0 = bound(y0, 0, type(uint112).max); - xt = bound(xt, 1 + x0 / 1e6, x0); // from 1 millionth of the reserves left up + xt = bound(xt, 1 + x0 / 1e3, x0); // thousand-fold price movement px = bound(px, 1, 1e36); py = bound(py, 1, 1e36); c = bound(c, 1, 1e18); eulerSwap.f(xt, px, py, x0, y0, c); } + */ } From 5c4aae8cf776f10d454046e0e98284a576e4d873 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 3 Mar 2025 00:05:51 +0900 Subject: [PATCH 155/312] fix --- test/EulerSwapFactoryTest.t.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index 384fdb3..cfd8afc 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -21,7 +21,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { bytes32 salt = bytes32(uint256(1234)); IEulerSwap.Params memory poolParams = IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 0); - IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 50e18, 50e18); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); address predictedAddress = predictPoolAddress(address(eulerSwapFactory), poolParams, curveParams, salt); @@ -74,7 +74,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { function testDeployWithAssetsOutOfOrderOrEqual() public { bytes32 salt = bytes32(uint256(1234)); IEulerSwap.Params memory poolParams = IEulerSwap.Params(address(eTST), address(eTST), holder, 1e18, 1e18, 0); - IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 50e18, 50e18); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); vm.prank(holder); vm.expectRevert(EulerSwap.AssetsOutOfOrderOrEqual.selector); @@ -84,10 +84,10 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { function testDeployWithBadFee() public { bytes32 salt = bytes32(uint256(1234)); IEulerSwap.Params memory poolParams = IEulerSwap.Params(address(eTST), address(eTST2), holder, 1e18, 1e18, 1e18); - IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 50e18, 50e18); + IEulerSwap.CurveParams memory curveParams = IEulerSwap.CurveParams(0.4e18, 0.85e18, 1e18, 1e18); vm.prank(holder); - vm.expectRevert(EulerSwap.BadFee.selector); + vm.expectRevert(EulerSwap.BadParam.selector); eulerSwapFactory.deployPool(poolParams, curveParams, salt); } From 8d74ce3d56e02f90f0a9131ae70b9e983bf9c542 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 3 Mar 2025 00:21:12 +0900 Subject: [PATCH 156/312] chore: re-add events --- src/EulerSwap.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 46a11bf..1bceb06 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -36,6 +36,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { uint112 public reserve1; uint32 public status; // 0 = unactivated, 1 = unlocked, 2 = locked + event EulerSwapCreated(address indexed asset0, address indexed asset1); event Swap( address indexed sender, uint256 amount0In, @@ -94,6 +95,8 @@ contract EulerSwap is IEulerSwap, EVCUtil { priceY = curveParams.priceY; concentrationX = curveParams.concentrationX; concentrationY = curveParams.concentrationY; + + emit EulerSwapCreated(asset0Addr, asset1Addr); } /// @inheritdoc IEulerSwap From 8bc8a77934a454ab78ee21f5fd4dcf9faf293c96 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 3 Mar 2025 01:01:30 +0900 Subject: [PATCH 157/312] chore: rename to eulerAccount --- docs/interfaces.md | 2 +- src/EulerSwap.sol | 26 +++++++++++++------------- src/EulerSwapFactory.sol | 8 ++++---- src/EulerSwapPeriphery.sol | 2 +- src/interfaces/IEulerSwap.sol | 4 ++-- test/EulerSwapFactoryTest.t.sol | 2 +- test/EulerSwapTestBase.t.sol | 2 +- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/interfaces.md b/docs/interfaces.md index c389f1e..a69724f 100644 --- a/docs/interfaces.md +++ b/docs/interfaces.md @@ -42,7 +42,7 @@ The `IEulerSwap` interface defines the core functionality for executing token sw - **description**: Returns the address of asset 1. -#### `myAccount() external view returns (address);` +#### `eulerAccount() external view returns (address);` - **description**: Returns the address of the account managing EulerSwap. diff --git a/src/EulerSwap.sol b/src/EulerSwap.sol index 1bceb06..a9e3695 100644 --- a/src/EulerSwap.sol +++ b/src/EulerSwap.sol @@ -20,7 +20,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { address public immutable vault1; address public immutable asset0; address public immutable asset1; - address public immutable myAccount; + address public immutable eulerAccount; uint112 public immutable debtLimit0; uint112 public immutable debtLimit1; uint112 public immutable initialReserve0; @@ -82,7 +82,7 @@ contract EulerSwap is IEulerSwap, EVCUtil { vault1 = params.vault1; asset0 = asset0Addr; asset1 = asset1Addr; - myAccount = params.myAccount; + eulerAccount = params.eulerAccount; debtLimit0 = params.debtLimit0; debtLimit1 = params.debtLimit1; initialReserve0 = reserve0 = offsetReserve(params.debtLimit0, params.vault0); @@ -178,8 +178,8 @@ contract EulerSwap is IEulerSwap, EVCUtil { IAllowanceTransfer(permit2).approve(asset1, vault1, type(uint160).max, type(uint48).max); } - IEVC(evc).enableCollateral(myAccount, vault0); - IEVC(evc).enableCollateral(myAccount, vault1); + IEVC(evc).enableCollateral(eulerAccount, vault0); + IEVC(evc).enableCollateral(eulerAccount, vault1); } /// @inheritdoc IEulerSwap @@ -198,30 +198,30 @@ contract EulerSwap is IEulerSwap, EVCUtil { if (balance > 0) { uint256 avail = amount < balance ? amount : balance; - IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IERC4626.withdraw, (avail, to, myAccount))); + IEVC(evc).call(vault, eulerAccount, 0, abi.encodeCall(IERC4626.withdraw, (avail, to, eulerAccount))); amount -= avail; } if (amount > 0) { - IEVC(evc).enableController(myAccount, vault); - IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IBorrowing.borrow, (amount, to))); + IEVC(evc).enableController(eulerAccount, vault); + IEVC(evc).call(vault, eulerAccount, 0, abi.encodeCall(IBorrowing.borrow, (amount, to))); } } function depositAssets(address vault, uint256 amount) internal returns (uint256) { - try IEVault(vault).deposit(amount, myAccount) {} + try IEVault(vault).deposit(amount, eulerAccount) {} catch (bytes memory reason) { require(bytes4(reason) == EVKErrors.E_ZeroShares.selector, DepositFailure(reason)); return 0; } - if (IEVC(evc).isControllerEnabled(myAccount, vault)) { + if (IEVC(evc).isControllerEnabled(eulerAccount, vault)) { IEVC(evc).call( - vault, myAccount, 0, abi.encodeCall(IBorrowing.repayWithShares, (type(uint256).max, myAccount)) + vault, eulerAccount, 0, abi.encodeCall(IBorrowing.repayWithShares, (type(uint256).max, eulerAccount)) ); if (myDebt(vault) == 0) { - IEVC(evc).call(vault, myAccount, 0, abi.encodeCall(IRiskManager.disableController, ())); + IEVC(evc).call(vault, eulerAccount, 0, abi.encodeCall(IRiskManager.disableController, ())); } } @@ -229,11 +229,11 @@ contract EulerSwap is IEulerSwap, EVCUtil { } function myDebt(address vault) internal view returns (uint256) { - return IEVault(vault).debtOf(myAccount); + return IEVault(vault).debtOf(eulerAccount); } function myBalance(address vault) internal view returns (uint256) { - uint256 shares = IEVault(vault).balanceOf(myAccount); + uint256 shares = IEVault(vault).balanceOf(eulerAccount); return shares == 0 ? 0 : IEVault(vault).convertToAssets(shares); } diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 8828701..950e07a 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -47,11 +47,11 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { external returns (address) { - require(_msgSender() == params.myAccount, Unauthorized()); + require(_msgSender() == params.eulerAccount, Unauthorized()); - EulerSwap pool = new EulerSwap{salt: keccak256(abi.encode(params.myAccount, salt))}(params, curveParams); + EulerSwap pool = new EulerSwap{salt: keccak256(abi.encode(params.eulerAccount, salt))}(params, curveParams); - checkSwapAccountOperators(params.myAccount, address(pool)); + checkSwapAccountOperators(params.eulerAccount, address(pool)); allPools.push(address(pool)); @@ -63,7 +63,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { params.vault0, params.vault1, pool.feeMultiplier(), - params.myAccount, + params.eulerAccount, curveParams.priceX, curveParams.priceY, curveParams.concentrationX, diff --git a/src/EulerSwapPeriphery.sol b/src/EulerSwapPeriphery.sol index 5d5d26a..7adf97d 100644 --- a/src/EulerSwapPeriphery.sol +++ b/src/EulerSwapPeriphery.sol @@ -89,7 +89,7 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery { returns (uint256) { require( - IEVC(eulerSwap.EVC()).isAccountOperatorAuthorized(eulerSwap.myAccount(), address(eulerSwap)), + IEVC(eulerSwap.EVC()).isAccountOperatorAuthorized(eulerSwap.eulerAccount(), address(eulerSwap)), OperatorNotInstalled() ); diff --git a/src/interfaces/IEulerSwap.sol b/src/interfaces/IEulerSwap.sol index 275d068..1ad0676 100644 --- a/src/interfaces/IEulerSwap.sol +++ b/src/interfaces/IEulerSwap.sol @@ -5,7 +5,7 @@ interface IEulerSwap { struct Params { address vault0; address vault1; - address myAccount; + address eulerAccount; uint112 debtLimit0; uint112 debtLimit1; uint256 fee; @@ -45,7 +45,7 @@ interface IEulerSwap { function vault1() external view returns (address); function asset0() external view returns (address); function asset1() external view returns (address); - function myAccount() external view returns (address); + function eulerAccount() external view returns (address); function initialReserve0() external view returns (uint112); function initialReserve1() external view returns (uint112); function feeMultiplier() external view returns (uint256); diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index cfd8afc..249a42e 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -104,7 +104,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { abi.encodePacked( bytes1(0xff), factoryAddress, - keccak256(abi.encode(address(poolParams.myAccount), salt)), + keccak256(abi.encode(address(poolParams.eulerAccount), salt)), keccak256( abi.encodePacked(type(EulerSwap).creationCode, abi.encode(poolParams, curveParams)) ) diff --git a/test/EulerSwapTestBase.t.sol b/test/EulerSwapTestBase.t.sol index 02bbe3e..faf30e8 100644 --- a/test/EulerSwapTestBase.t.sol +++ b/test/EulerSwapTestBase.t.sol @@ -149,7 +149,7 @@ contract EulerSwapTestBase is EVaultTestBase { return IEulerSwap.Params({ vault0: address(eTST), vault1: address(eTST2), - myAccount: holder, + eulerAccount: holder, debtLimit0: debtLimitA, debtLimit1: debtLimitB, fee: fee From 5598c4dc7a7da4df85aaaabee580e1166baf9932 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 3 Mar 2025 01:08:50 +0900 Subject: [PATCH 158/312] chore: rename to eulerAccount --- src/EulerSwapFactory.sol | 24 ++++++++++++------------ test/EulerSwapFactoryTest.t.sol | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index 950e07a..ae67de9 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -11,8 +11,8 @@ import {EVCUtil} from "ethereum-vault-connector/utils/EVCUtil.sol"; contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { /// @dev An array to store all pools addresses. address[] public allPools; - /// @dev Mapping between a swap account and deployed pool that is currently set as operator - mapping(address swapAccount => address operator) public swapAccountToPool; + /// @dev Mapping between a euler account and deployed pool that is currently set as operator + mapping(address eulerAccount => address operator) public eulerAccountToPool; event PoolDeployed( address indexed asset0, @@ -20,7 +20,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { address vault0, address vault1, uint256 indexed feeMultiplier, - address swapAccount, + address eulerAccount, uint256 priceX, uint256 priceY, uint256 concentrationX, @@ -37,7 +37,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { /// @notice Deploy a new EulerSwap pool with the given parameters /// @dev The pool address is deterministically generated using CREATE2 with a salt derived from - /// the swap account address and provided salt parameter. This allows the pool address to be + /// the euler account address and provided salt parameter. This allows the pool address to be /// predicted before deployment. /// @param params Core pool parameters including vaults, account, and fee settings /// @param curveParams Parameters defining the curve shape including prices and concentrations @@ -51,7 +51,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { EulerSwap pool = new EulerSwap{salt: keccak256(abi.encode(params.eulerAccount, salt))}(params, curveParams); - checkSwapAccountOperators(params.eulerAccount, address(pool)); + checkEulerAccountOperators(params.eulerAccount, address(pool)); allPools.push(address(pool)); @@ -97,20 +97,20 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { return allPoolsList; } - /// @notice Validates operator authorization for a swap account. First checks if the account has an existing operator + /// @notice Validates operator authorization for a euler account. First checks if the account has an existing operator /// and ensures it is deauthorized. Then verifies the new pool is authorized as an operator. Finally, updates the /// mapping to track the new pool as the account's operator. - /// @param swapAccount The address of the swap account. + /// @param eulerAccount The address of the euler account. /// @param newPool The address of the new pool. - function checkSwapAccountOperators(address swapAccount, address newPool) internal { - address operator = swapAccountToPool[swapAccount]; + function checkEulerAccountOperators(address eulerAccount, address newPool) internal { + address operator = eulerAccountToPool[eulerAccount]; if (operator != address(0)) { - require(!evc.isAccountOperatorAuthorized(swapAccount, operator), OldOperatorStillInstalled()); + require(!evc.isAccountOperatorAuthorized(eulerAccount, operator), OldOperatorStillInstalled()); } - require(evc.isAccountOperatorAuthorized(swapAccount, newPool), OperatorNotInstalled()); + require(evc.isAccountOperatorAuthorized(eulerAccount, newPool), OperatorNotInstalled()); - swapAccountToPool[swapAccount] = newPool; + eulerAccountToPool[eulerAccount] = newPool; } } diff --git a/test/EulerSwapFactoryTest.t.sol b/test/EulerSwapFactoryTest.t.sol index 249a42e..b7fa719 100644 --- a/test/EulerSwapFactoryTest.t.sol +++ b/test/EulerSwapFactoryTest.t.sol @@ -43,7 +43,7 @@ contract EulerSwapFactoryTest is EulerSwapTestBase { vm.prank(holder); evc.batch(items); - EulerSwap eulerSwap = EulerSwap(eulerSwapFactory.swapAccountToPool(holder)); + EulerSwap eulerSwap = EulerSwap(eulerSwapFactory.eulerAccountToPool(holder)); uint256 allPoolsLengthAfter = eulerSwapFactory.allPoolsLength(); assertEq(allPoolsLengthAfter - allPoolsLengthBefore, 1); From 987b8440418827a7a29dc9742ee579f608bd06e4 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Mon, 3 Mar 2025 01:09:57 +0900 Subject: [PATCH 159/312] chore: fix typos --- src/EulerSwapFactory.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EulerSwapFactory.sol b/src/EulerSwapFactory.sol index ae67de9..28ae63d 100644 --- a/src/EulerSwapFactory.sol +++ b/src/EulerSwapFactory.sol @@ -11,7 +11,7 @@ import {EVCUtil} from "ethereum-vault-connector/utils/EVCUtil.sol"; contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { /// @dev An array to store all pools addresses. address[] public allPools; - /// @dev Mapping between a euler account and deployed pool that is currently set as operator + /// @dev Mapping between euler account and deployed pool that is currently set as operator mapping(address eulerAccount => address operator) public eulerAccountToPool; event PoolDeployed( @@ -97,7 +97,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil { return allPoolsList; } - /// @notice Validates operator authorization for a euler account. First checks if the account has an existing operator + /// @notice Validates operator authorization for euler account. First checks if the account has an existing operator /// and ensures it is deauthorized. Then verifies the new pool is authorized as an operator. Finally, updates the /// mapping to track the new pool as the account's operator. /// @param eulerAccount The address of the euler account. From 44ae1a0209086383b4ca26c046fb102a644098ee Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 2 Mar 2025 21:59:17 +0000 Subject: [PATCH 160/312] fix: remove swap account language in architecture.md --- docs/architecture.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 424853c..fcbad7c 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -2,13 +2,11 @@ ## Overview -EulerSwap is an automated market maker (AMM) that integrates with Euler lending vaults to provide deeper liquidity for swaps. - -Unlike traditional AMMs that use shared liquidity pools, EulerSwap operates with independent swap accounts, where each account manages liquidity for a single user or entity. +EulerSwap is an automated market maker (AMM) that integrates with Euler credit vaults to provide deeper liquidity for swaps. Each EulerSwap instance is a lightweight smart contract that functions as an [EVC operator](https://evc.wtf/docs/whitepaper/#operators) while implementing a highly customizable AMM curve to determine swap output amounts. -When a user initiates a swap, the swap account borrows the required output token using the input token as collateral. The swap account’s AMM curve governs the exchange rate, ensuring deep liquidity over short timeframes while maintaining a balance between collateral and debt over the long term. +When a user initiates a swap, the EulerSwap operator borrows the required output token using the input token as collateral. The operator’s internal AMM curve governs the exchange rate, ensuring deep liquidity over short timeframes while maintaining a balance between collateral and debt over the long term. ## Code structure @@ -16,7 +14,7 @@ EulerSwap’s code is split into two main smart contracts: ### EulerSwap core (`EulerSwap.sol`) -- Handles collateralization via EVC and Euler lending vaults. +- Handles collateralization via EVC and Euler credit vaults. - Implements AMM curve invariant checks through the `verify()` function. ### EulerSwap periphery (`EulerSwapPeriphery.sol`) @@ -26,10 +24,10 @@ EulerSwap’s code is split into two main smart contracts: ## Operational flow -The following steps outline how a swap account is created and configured: +The following steps outline how an EulerSwap operator is created and configured: -1. Deposit initial liquidity into one or both of the vaults to enable swaps. -2. Deploy the EulerSwap contract, specifying AMM curve parameters and the `fee`. +1. Deposit initial liquidity into one or both of the underlying credit vaults to enable swaps. +2. Deploy an instance of EulerSwap, specifying AMM curve parameters and the `fee`. 3. Set the [virtual reserves](#virtual-reserves) by invoking `setVirtualReserves()`. 4. Install the EulerSwap contract as an operator for the user's account. 5. Invoke the `configure()` function on the EulerSwap contract. From 9dcaad7ea09b7e90a0c7d5be34f25a32d716b947 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 2 Mar 2025 22:04:14 +0000 Subject: [PATCH 161/312] fix: whitepaper link in readme.md --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index abbbbe5..6f5ef24 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ # EulerSwap -EulerSwap is an Automated Market Maker (AMM) that uses [Euler lending vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) as leveraged lending products in order to extend the range of its reserves and thereby improve the capital efficiency of liquidity provisioning. +EulerSwap is an automated market maker (AMM) that integrates with Euler [credit vaults](https://docs.euler.finance/euler-vault-kit-white-paper/) to provide deeper liquidity for swaps. When a user initiates a swap, a smart contract called an EulerSwap operator borrows the required output token using the input token as collateral. This model enables up to 40x the liquidity depth of traditional AMMs by making idle assets in Euler more efficient. Unlike traditional AMMs, which often fragment liquidity across multiple pools, EulerSwap further increases capital efficiency by allowing a single, cross-collateralised credit vault to support multiple asset pairs at once. At its core, EulerSwap uses a flexible AMM curve to optimise swap pricing, ensuring deep liquidity while maintaining market balance. By combining just-in-time liquidity, shared liquidity across pools, and customisable AMM mechanics, EulerSwap reduces inefficiencies in liquidity provision, offering deeper markets, lower costs, and greater control for liquidity providers. -To swappers, EulerSwap presents a hopefully familiar Uniswap2-style interface but internally it supports borrow and repaying, custom pricing curves, and other advanced functionality. Although useable by anyone, it is primarily intended to be invoked by sophisticated actors such as swap aggregators, intents solvers, and MEV bots. Similar to Uniswap, there is a careful separation between the critical core functionality for servicing swaps and the surrounding periphery functions for quoting, etc. - -For more information, refer to the [white paper](./docs/white-paper/EulerSwap_White_Paper.pdf). +For more information, refer to the [white paper](./docs/whitepaper/EulerSwap_White_Paper.pdf). ## Usage @@ -54,7 +52,7 @@ Always include thorough tests when using EulerSwap to ensure it interacts correc ## Known limitations -Refer to the [white paper](./docs/white-paper/EulerSwap_White_Paper.pdf) for a list of known limitations and security considerations. +Refer to the [white paper](./docs/whitepaper/EulerSwap_White_Paper.pdf) for a list of known limitations and security considerations. ## Contributing From 0e0f10ade54a693b22456d4aa5f69f56735cce40 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Sun, 2 Mar 2025 22:05:57 +0000 Subject: [PATCH 162/312] fix: typo in whitepaper --- docs/whitepaper/EulerSwap_White_Paper.pdf | Bin 356093 -> 358060 bytes docs/whitepaper/main.tex | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/whitepaper/EulerSwap_White_Paper.pdf b/docs/whitepaper/EulerSwap_White_Paper.pdf index af8879da6f4f7de762144857f42a359f690fb106..a7d4fd96fa0d4027fd33016d53cf8fba504359e2 100644 GIT binary patch delta 52225 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

gj)#7_>R&0lxB7pHrdAX-OskM4`f;p>ru< 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�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�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 diff --git a/docs/white-paper/curve.png b/docs/white-paper/curve.png deleted file mode 100644 index 59176ba7d8fc3119a72051a0a4b33dde2a6f3352..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 262544 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

3Aw+-y#Hac_g|sa|I=g- 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

>o|z4F#SvXV0t#Q?HP|H}87DU{eZkfe8=D6~nf) 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 literal 0 HcmV?d00001 diff --git a/docs/white-paper/main.tex b/docs/white-paper/main.tex new file mode 100644 index 0000000..7ae8c72 --- /dev/null +++ b/docs/white-paper/main.tex @@ -0,0 +1,499 @@ +\documentclass{article} + +% Encoding and Geometry +\usepackage[utf8]{inputenc} +\usepackage[a4paper, margin=1in]{geometry} % Standard 1-inch margins for better layout +\usepackage{parskip} + +% Math Packages +\usepackage{amsmath, amsfonts, mathtools} + +% Graphics and Figures +\usepackage{graphicx} +\usepackage{caption} +\usepackage{subcaption} +\usepackage{multirow} +\usepackage{tikz} +\usetikzlibrary{positioning} % Ensures compatibility with Overleaf + +% Hyperlinks +\usepackage[colorlinks=true, linkcolor=blue, urlcolor=blue]{hyperref} % Load last to avoid conflicts + +% Floating Objects Placement +\usepackage[section]{placeins} + +% Bibliography +\usepackage[ + backend=biber, + style=alphabetic, + sorting=ynt +]{biblatex} +\addbibresource{references.bib} + +% Title Information +\title{Maglev White Paper} +\author{Euler Labs} % Optionally add an author here +\date{February 2025} + +\begin{document} + +\maketitle + +\begin{abstract} + Maglev is an Automated Market Maker (AMM) that uses unique features of Euler lending vaults to \textbf{mag}nify capital efficiency using \textbf{lev}erage. By borrowing assets as needed, Maglev AMMs can extend the range of their reserves and earn fees on trades several times larger than their actual liquidity. Under optimal conditions, Maglev can achieve up to 40x the liquidity depth of traditional AMMs. Using the Ethereum Vault Connector (EVC), Maglev enables market makers to efficiently borrow the `out token' of a swap using the `in token' as collateral. This significantly improves liquidity for swappers. A novel and highly customisable AMM curve governs swap exchange rates, ensuring deep just-in-time liquidity in the short term while incentivising balance over longer periods. +\end{abstract} + +\section{Introduction} + +Maglev enhances trade execution by increasing the size of swaps that can be serviced compared to traditional AMMs. This is made possible by combining a novel AMM curve with the advanced \href{https://docs.euler.finance/developers/evc/keyConcepts?_highlight=operator#batch-operations}{check deferrals} and \href{https://docs.euler.finance/developers/evc/keyConcepts?_highlight=operator#operators}{operator} features of the Ethereum Vault Connector (EVC). Market makers supply an initial amount of liquidity to a `swap account' which can then be amplified through borrowing. Specifically, when a user swaps an `in token,' Maglev borrows the corresponding `out token,' using the `in token' as collateral. Later, when a swap occurs in the reverse direction, the incoming `in token' repays the outstanding loan, and any excess collateral is returned as the `out token,' effectively closing the position. This leveraged approach significantly increases the available liquidity provided by Maglev and multiplies swap fees. It is somewhat analogous to MEV bots that provide just-in-time single-tick liquidity to Uniswap v3 in order to capture fees on large trades. + +Maglev’s exchange rates are governed by a highly customisable AMM curve (illustrated in Figure \ref{fig:fig1}) which incentivises swappers to maintain market maker positions in balance over time. The Maglev AMM curve is a novel construction blending constant-sum and constant-product models, allowing swap account creators to tailor their AMM parameters. Like \href{https://berkeley-defi.github.io/assets/material/StableSwap.pdf}{Stableswap}, it supports concentrated liquidity for correlated assets, as well as \href{https://app.uniswap.org/whitepaper.pdf}{Uniswap v2}-style distributed liquidity for uncorrelated pairs. However, unlike those more traditional AMMs, Maglev allows asymmetric liquidity deposits, where different amounts of liquidity can be added to each side of the pool, and single-sided liquidity concentration, enabling deeper concentration of liquidity on one side of the pool relative to the other. This enables it to simulate the behaviour of atypical AMM protocols, like the MakerDAO \href{https://mips.makerdao.com/mips/details/MIP29}{Peg Stability Module} (PSM). + +For end-users, Maglev functions like a typical Uniswap-style interface. However, behind the scenes, it incorporates advanced mechanisms such as borrowing and repaying, custom pricing curves, and dynamic liquidity provisioning. The main target audience for liquidity providers in Maglev AMMs are professional market makers, token issuers, and other DAOs, whilst the main target audience for swappers are leverage traders on Euler, aggregators, intent solvers, and MEV bots. + +\section{Example} + +Suppose that Euler allows borrowing of USDT with USDC as collateral at a loan-to-value (LTV) ratio of 0.95, and vice versa. This means that for every \$1 of USDC or USDT collateral, a user can borrow up to \$0.95 of the other asset. + +Now suppose you have a swap account with 1M USDC deposited as initial liquidity. Using maximum leverage your account could support deposits of 20M USDC and debts of 19M USDT. Alternatively, if you swapped your 1 million USDC to 1 million USDT, it could support the opposite. Let’s say another user wants to swap 10M USDC for USDT. The steps are as follows: + +\begin{enumerate} + \item They send 10M USDC to your swap account as the swap input. + \item Your swap account deposits the 10M USDC as collateral in Euler. + \item Your swap account borrows approximately 10M USDT against the account's collateral, which includes your original deposit, alongside the swap input. + \item It sends the borrowed USDT to the user as the swap output. +\end{enumerate} + +\quad +Importantly, this isn’t a 1:1 swap because: a) you charge a fee for facilitating the swap; and b) the exact swap output is determined by an AMM curve, which factors in increasingly large price impact as the swap input amount increases. After the swap, your swap account now holds 11M USDC deposits and 10M USDT debt. It earns interest on the supplied USDC but must also pay interest on the borrowed USDT. + +Later, when a swap occurs in the reverse direction, the incoming `in token' repays the outstanding loan, and any excess collateral is returned as the `out token.' The AMM curve dynamically adjusts incentives such that imbalances encourage swaps in the opposite direction, facilitating natural rebalancing. This mechanism ensures that positions do not remain open for extended periods, reducing exposure to borrowing costs. Over time, you will incur costs due to small interest rate differentials, whilst generating significant swap fees through utilisation of idle liquidity in the lending protocol. The whole process is depicted in Fig. \ref{fig:maglev_liquidity}. + +\bigskip +\begin{figure}[h] + \centering + \begin{tikzpicture}[ + node distance=1cm, + every node/.style={draw, text width=2.5cm, align=center, rounded corners} + ] + % Nodes + \node (user1) {User Sends 10M USDC}; + \node (maglev) [right=of user1] {Maglev Swap Account}; + \node (deposit) [below=of maglev] {Deposits 10M USDC as Collateral}; + \node (borrow) [below=of deposit] {Borrows ~10M USDT}; + \node (user2) [left=of borrow] {User Receives 10M USDT}; + + % Arrows + \draw[->] (user1) -- (maglev); + \draw[->] (maglev) -- (deposit); + \draw[->] (deposit) -- (borrow); + \draw[->] (borrow) -- (user2); + \end{tikzpicture} + \caption{\textbf{Swap flow in Maglev AMM}. Maglev’s just-in-time liquidity borrowing. The swap account dynamically increases liquidity by borrowing the ``out token" against the ``in token."} + \label{fig:maglev_liquidity} +\end{figure} + +\section{Curve} + +The space of possible reserves in a Maglev AMM is determined by how much debt a swap account is allowed to hold. The Maglev curve passes through an equilibrium point $(x_0, y_0)$, at which the marginal price is defined by: + +\begin{equation} +\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}. +\end{equation} + +Unlike most AMM curves, which are usually defined by a single convex function, Maglev uses a piecewise-defined curve, with different functions providing trading behaviour either side of the equilibrium point: + +\begin{equation} + \label{eq:fx-main} + f(x) = + \begin{dcases} + f_1(x), + & 0 < x \leq x_0 \\ + f_2(x), + & x_0 < x + \end{dcases}. +\end{equation} + +In the domain $0 < x \leq x_0$, the curve is defined by + +\begin{equation} + \label{eq:fx1-main} + f_1(x) + = + y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-x\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{x}\right)\right). +\end{equation} + +In the domain $x_0 < x$, the curve is defined by + +\begin{equation} + \label{eq:fx2-main} + f_2(x) + = + \frac{ + \sqrt{ + \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right)^2 + + 4c_y (1 - c_y) y_0^2 + } + - \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right) + }{2c_y}. +\end{equation} + + The curve coefficients in these equations, \( c_x, c_y \in [0, 1] \), represent liquidity concentration parameters, determining how steeply the curve slopes to the left and right of the equilibrium point $(x_0, y_0)$. When \( c_x, c_y \) are close to 1, the curve behaves more like a constant-sum AMM, while for values close to 0, it behaves more like a constant-product AMM. A full derivation is given in the Appendix \ref{sec:curve-derivation}. + + \begin{figure}[h] % 'h' places it here, 't' for top, 'b' for bottom, 'p' for separate page + \centering % Centers the image + \includegraphics[width=0.5\textwidth]{curve.png} % Adjust width as needed + \caption{\textbf{Maglev AMM curve.} The Maglev curve (red line) consists of two sides with separate reserve values $x_0, y_0$ and concentration parameters $c_x, c_y$, allowing liquidity to be distributed asymmetrically. This means liquidity can be more or less dense or concentrated on one side of the AMM relative to the other. The exchange rate at equilibrium is determined by the pricing parameters $p_x, p_y$ and is fully flexible. You can interact with the curve \href{https://www.desmos.com/calculator/gzwmvbs1dk}{here} on Desmos to compare its behavior with traditional constant-sum and constant-product curves (black lines).} + \label{fig:fig1} % Useful for referencing the figure in text +\end{figure} + +\section{Conclusion} + +Maglev enhances Automated Market Making by leveraging just-in-time borrowing to expand liquidity depth dynamically. By integrating Euler’s lending vaults, it enables market makers to amplify positions efficiently while offering a customizable AMM curve that supports concentrated, distributed, and asymmetric liquidity structures. These features make Maglev adaptable to a wide range of trading strategies. However, this efficiency is not without some trade-offs. Swap accounts incur interest costs on borrowed assets, which can erode profitability if not offset by swap fees, interest on collateral, or token incentives. Additionally, Maglev inherits Euler’s risk parameters, making it most effective for correlated asset pairs with high loan-to-value (LTV) ratios, while volatile assets pose higher liquidation risks if positions become imbalanced. Despite these trade-offs, Maglev represents a breakthrough in AMM design by repurposing idle liquidity in lending protocols, reducing capital inefficiencies, and optimizing swap execution. By catering to professional market makers, DAOs, and algorithmic traders, it positions itself as a powerful tool for on-chain liquidity optimization. + +\section*{Acknowledgments} + +During a security review of Maglev, Chris Michel noted similarities between some of its underlying concepts and BlackHoleSwap, a project prototype he had reviewed years earlier. While Maglev was designed independently and without influence from that project, the resemblance is significant enough to warrant its recognition here as prior art. + +\newpage +\section{Appendix} + +\subsection{Curve derivation} +\label{sec:curve-derivation} + +We start with an AMM containing reserves (initial liquidity) of two assets, \( x_0 \) and \( y_0 \), and define two standard AMM curve models. + +\subsubsection{Constant-sum and constant-product AMM curves} + +The constant-sum and constant-product AMM curves are given by: + +\begin{align} + x + y &= x_0 + y_0, \\ + xy &= x_0 y_0. +\end{align} + +These curves intersect at the point \( (x_0, y_0) \), where their slope is: + +\[ +\frac{dy}{dx} \Big|_{(x_0, y_0)} = -1. +\] + +To introduce arbitrary pricing, we extend these curves by adding pricing parameters \( p_x \) and \( p_y \). + +\subsubsection{Generalising to arbitrary pricing} + +We define new AMM equations incorporating custom pricing: + +\begin{align} + p_x x + p_y y &= p_x x_0 + p_y y_0, \\ + \label{eq:exponential-form} + x^{p_y y_0} y^{p_x x_0} &= x_0^{p_y y_0} y_0^{p_x x_0}. +\end{align} + +Taking the derivatives of these equations with respect to \( x \), we obtain: + +\begin{align} + \frac{dy}{dx} &= -\frac{p_x}{p_y}, \\ + \frac{dy}{dx} &= -\frac{p_x}{p_y} \frac{x_0 y}{y_0 x}. +\end{align} + +These results confirm that at equilibrium \( (x_0, y_0) \), the slope is: + +\[ +\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}. +\] + +However, equation \eqref{eq:exponential-form} involves an exponential form, which makes it difficult to evaluate numerically. To resolve this, we introduce the concept of virtual reserves. + +\subsubsection{Introducing virtual reserves for simplicity} + +Note that in the interval $0 < x < x_0$ trading should not depend on the initial amount of $y_0$ liquidity. Swaps from should only increase liquidity beyond $y_0$ and deplete the $x_0$ liquidity. This suggests that we can split the domain of the AMM curves into two, and replace the real reserve $y_0$ in the interval $0 < x < x_0$ with an idealised virtual reserve $y_v$. Using the equilibrium condition: + +\[ +p_x x_0 = p_y y_0, +\] + +we derive: + +\[ +y_v = x_0 \frac{p_x}{p_y}. +\] + +Substituting into our pricing equations and simplifying, we obtain two modified AMM equations: + +\begin{align} + y &= \frac{p_x}{p_y} (2x_0 - x), \\ + y &= \frac{p_x}{p_y} \frac{x_0^2}{x}. +\end{align} + +Since these curves no longer pass through \( (x_0, y_0) \), we correct them by adding back the difference \( y_0 - p_x / p_y x_0 \), leading to: + +\begin{align} + y &= y_0 + \frac{p_x}{p_y} (x_0 - x), \\ + y &= y_0 + \frac{p_x}{p_y} (x_0 - x) \left( \frac{x_0}{x} \right). +\end{align} + +\subsubsection{Unifying into a single curve} + +To create a single unified curve, we introduce a liquidity concentration parameter \( c_x \), which determines the curve’s behavior: + +\begin{itemize} + \item When \( c_x = 1 \), the AMM functions as a constant-sum model. + \item When \( c_x = 0 \), the AMM behaves as a standard constant-product AMM. + \item Intermediate values of \( c_x \) create a hybrid liquidity curve. +\end{itemize} + +This gives the final equation: + +\begin{equation} + \label{eq:maglev-1} + y = y_0 + \frac{p_x}{p_y} (x_0 - x) \left( c_x + (1 - c_x) \left(\frac{x_0}{x}\right) \right). +\end{equation} + +This is equivalent to the function \( f_1(x) \) given by equation \eqref{eq:fx1-main} in the main text. + +\subsubsection{Extending the curve to the \( x > x_0 \) region} + +For \( x > x_0 \), we construct a reflected curve that also passes through \( (x_0, y_0) \) and maintains the required derivative: + +\begin{equation} + \label{eq:maglev-3-inverse} + x = x_0 + \frac{p_y}{p_x} (y_0 - y) \left( c_y + (1 - c_y) \left(\frac{y_0}{y}\right) \right). +\end{equation} + +Since this equation defines \( x \) in terms of \( y \), we invert it by solving for \( y \), leading to the quadratic equation: + +\begin{equation} + y = c_y y^2 + \left( \frac{p_x}{p_y} (x - x_0) - y_0(2c_y - 1) \right)y - (1 - c_y) y_0^2. +\end{equation} + +Taking only the positive real root, we obtain: + +\begin{equation} + \label{eq:maglev-2} + y = \frac{ + \sqrt{ + \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right)^2 + + 4c_y (1 - c_y) y_0^2 + } + - \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right) + }{2c_y}. +\end{equation} + +This corresponds to the function \( f_2(x) \) given by equation \eqref{eq:fx2-main} in the main text. + +\subsection{Invariant derivation} +\label{sec:invariant-derivation} + +In traditional AMM protocols, the curve is typically defined as an implicit function of $y$. For example, the classic Uniswap AMM follows a constant-product equation: + +\begin{equation} + xy = x_0 y_0 +\end{equation} + +where $x_0$ and $y_0$ are the initial liquidity reserves. This equation defines an invariant condition, ensuring that any valid swap must satisfy: + +\begin{equation} + xy \geq x_0 y_0. +\end{equation} + +This condition guarantees that after any trade, the product of the new reserves remains at least as large as the initial product, ensuring that swaps cannot drain liquidity from the pool. + +Rearranging this condition, we can express the invariant as a lower bound for $y$: + +\begin{equation} + y \geq \frac{x_0 y_0}{x}. +\end{equation} + +This means that for any valid trade, the resulting reserve state must lie on or above the AMM curve. + +\subsubsection{Extending the invariant to Maglev} + +For Maglev, we apply a similar principle. Given any reserve state $(x, y)$, we check whether it satisfies an equivalent invariant condition. + +From equation \eqref{eq:maglev-1}, for values where \( x \leq x_0 \), the AMM curve constraint requires: + +\begin{equation} + \label{eq:invariant-x1} + y \geq y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-x\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{x}\right)\right). +\end{equation} + +For values where \( x > x_0 \), we could derive a similar condition for $y$ from equation \eqref{eq:maglev-2}. However, a simpler and computationally cheaper approach is to use the inverse equation \eqref{eq:maglev-3-inverse}, which defines the lower bound for $x$ instead: + +\begin{equation} + \label{eq:invariant-x2} + x \geq x_{0}+\frac{p_{y}}{p_{x}}\left(y_{0}-y\right)\left(c_{y}+\left(1-c_{y}\right)\left(\frac{y_{0}}{y}\right)\right). +\end{equation} + +These conditions together define the valid liquidity states in Maglev, ensuring that the AMM remains balanced while allowing for greater flexibility in liquidity provisioning. + + + +\end{document} + + + + + + +\subsection{Curve derivation} + +We begin with initial liquidity in two assets $x_0$ and $y_0$. Basic constant-sum and constant-product AMM curves are given by + +\begin{align} + x + y + &= + x_0 + y_0, \; \text{and}, \\ + xy + &= + x_0 y_0, +\end{align} + +respectively. These curves pass through the point $(x_0, y_0)$, where they both have a slope given by $\frac{dy}{dx} \Big|_{(x_0, y_0)} = -1$. Suppose we want to find curves that allow for an arbitrary price at the point $(x_0, y_0)$. We can generalise the AMM curves above by defining pricing parameters $p_x$ and $p_y$, such that + +\begin{align} + \label{eq:cs-2} + p_x x + p_y y + &= + p_x x_0 + p_y y_0, \; \text{and}, \\ + \label{eq:cp-2} + x^{p_y y_0} y^{p_x x_0} + &= + x_0^{p_y y_0} y_0^{p_x x_0}. +\end{align} + +Implicit differentiation with respect to $x$ shows that their derivatives are given by + +\begin{align} + \frac{dy}{dx} + &= + -\frac{p_x}{p_y}, \; \text{and}, \\ + \frac{dy}{dx} + &= + -\frac{p_x}{p_y} \frac{x_0 y}{y_0 x}. +\end{align} + +Thus the new curves pass through the point $(x_0, y_0)$, where they both have a slope given by $\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}$. Unfortunately, \eqref{eq:cp-2} is difficult to evaluate numerically due to its exponent form. We can simplify the system to resolve this issue in the following way. + +Note that in the interval $0 < x < x_0$ the trading function of the AMM does not depend on the initial amount of $y_0$ liquidity, and in the interval $0 < y < y_0$ the trading function of the AMM does not depend on the initial amount of $x_0$ liquidity. This suggests that we can split the domain of the AMM curves into two, and replace the real reserve $y_0$ in the interval $0 < x < x_0$ with an idealised virtual reserve $y_v$, and vice versa. + +To find the idealised virtual reserves $y_v$, note that the new curves will still need to meet at the equilibrium point $(x_0, y_0)$ if we are to maintain a continuous trading function. In equilibrium, we know from equation \eqref{eq:cs-2} that $p_x x_0 = p_y y_0$. Thus our choices for virtual reserves must be $p_x x_0 = p_y y_v \implies y_v = x_0 (p_x /p_y)$. Substituting this back into equations \eqref{eq:cs-2} and \eqref{eq:cp-2} for $x_0$, simplifying, and rearranging to solve for $y$, we obtain + +\begin{align} + \label{eq:cs-3} + y + &= + \frac{p_x}{p_y} (2x_0 - x), \; \text{and}, \\ + \label{eq:cp-3} + y + &= + \frac{p_x}{p_y} \frac{x_0^2}{x}. +\end{align} + +These curves no longer pass through the equilibrium point $(x_0, y_0)$, so we add back in the difference $y_0 - p_x / p_y x_0$, giving + +\begin{align} + \label{eq:cs-4} + y + &= + y_0 + \frac{p_x}{p_y} (x_0 - x), \; \text{and}, \\ + \label{eq:cp-4} + y + &= + y_0 + \frac{p_x}{p_y} (x_0 - x) \left( \frac{x_0}{x} \right). +\end{align} + +We now combine these equations into a single curve parameterised by a liquidity concentration parameter $c_x$. When liquidity is maximally concentrated, we want our new curve to be equivalent to the constant-sum equation \eqref{eq:cs-4}, and when liquidity is maximally distributed, we want our new curve to be equivalent to the constant-product equation \eqref{eq:cp-4}. Thus we have + +\begin{equation} + \label{eq:ce-x} + y + = + y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-x\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{x}\right)\right). +\end{equation} + +This is equivalent to what is called $f_1(x)$ given by equation \eqref{eq:fx1-main} +in the main text. + +It is important to remember that this curve only provides a suitable trading function in the interval $0 < x < x_0$ where our assumption about virtual $y$ reserves holds true. We now consider what a suitable curve might be for the region $x > x_0$. Note that this region is equivalent to the interval $0 < y < y_0$ on the $y$-axis. The curve we seek is something like a reflection of equation \eqref{eq:ce-x}, except that it should also pass through the point $(x_0, y_0)$ and have derivative given by $\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}$. First taking the reflection, we have + +\begin{equation} + \label{eq:ce-x-reflection} + x + = + y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-y\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{y}\right)\right). +\end{equation} + +To force the reflection through the equilibrium point $(x_0, y_0)$ we can simply switch $x_0$ and $y_0$, and to force it to have have derivative given by $\frac{dy}{dx} \Big|_{(x_0, y_0)} = -\frac{p_x}{p_y}$ at that point, we can simply switch $p_x$ and $p_y$. Finally, we might as well allow this new curve to have its own liquidity concentration parameter, $c_y$. Making these substitutions, we have + +\begin{equation} + \label{eq:ce-y-1} + x + = + x_{0}+\frac{p_{y}}{p_{x}}\left(y_{0}-y\right)\left(c_{y}+\left(1-c_{y}\right)\left(\frac{y_{0}}{y}\right)\right). +\end{equation} + +This equation allows us to calculate $x$ in terms of $y$, but we would ideally like the opposite. We therefore solve for $y$ to invert the equation. This gives rise to a quadratic equation of the form + +\begin{equation} + \label{eq:ce-y-2} + y + = + c_{y}y^{2}+\left(\frac{p_{x}}{p_{y}}\left(x-x_{0}\right)-y_{0}\left(2c_{y}-1\right)\right)y-\left(1-c_{y}\right)y_{0}^{2}. +\end{equation} + +Since we are only interested in the positive real root of this equation, we have + +\begin{equation} + \label{eq:ce-y-3} + y + = + \frac{ + \sqrt{ + \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right)^2 + + 4c_y (1 - c_y) y_0^2 + } + - \left( \frac{p_x}{p_y} (x - x_0) + y_0 (1 - 2c_y) \right) + }{2c_y}. +\end{equation} + +This is equivalent to what is called $f_2(x)$ given by equation \eqref{eq:fx2-main} +in the main text. + +\subsection{Invariant derivation} + +On traditional AMM protocols, a curve is usually defined as an implicit function of $y$. For example, the classic Uniswap curve is given by a implicit equation of the form + +\begin{equation} + xy = x_0 y_0 +\end{equation} + +for some initial liquidity values $x_0$ and $y_0$. This gives rise to a natural invariant, where any swap input / output amount is allowed, providing the following invariant condition holds: + +\begin{equation} + xy \geq x_0 y_0. +\end{equation} + +It is easy to see that this kind of invariant can rearranged and replaced with an invariant of the form + +\begin{equation} + y \geq \frac{x_0 y_0}{x}. +\end{equation} + +This is essentially a test that valid states in the AMM are those for which the $y$-value is on or above the AMM curve. Similarly, on Maglev, for any point $(x, y)$, we can simply confirm from equation \eqref{eq:ce-x} that when $x \leq x_0$ we also have + +\begin{equation} + \label{eq:invariant-x1} + y + \geq + y_{0}+\frac{p_{x}}{p_{y}}\left(x_{0}-x\right)\left(c_{x}+\left(1-c_{x}\right)\left(\frac{x_{0}}{x}\right)\right) +\end{equation} + +When $x > x_0$ we could also define an invariant test for $y$ from equation \eqref{eq:ce-y-3}. However, it is simpler and cheaper computationally to use the inverse equation \eqref{eq:ce-y-1} and check that when $x > x_0$ we also have + +\begin{equation} + \label{eq:invariant-x2} + x + \geq + x_{0}+\frac{p_{y}}{p_{x}}\left(y_{0}-y\right)\left(c_{y}+\left(1-c_{y}\right)\left(\frac{y_{0}}{y}\right)\right). +\end{equation} diff --git a/docs/white-paper/references.bib b/docs/white-paper/references.bib new file mode 100644 index 0000000..11b9ea5 --- /dev/null +++ b/docs/white-paper/references.bib @@ -0,0 +1,91 @@ +@article{curvev2, + author = "Michael Egorov", + title = "Automatic market-making with dynamic peg", + journal = "", + volume = "", + number = "", + pages = "", + year = "2021", + DOI = "https://classic.curve.fi/files/crypto-pools-paper.pdf", + keywords = "amm" +} +@article{curvev1, + author = "Michael Egorov", + title = "StableSwap - efficient mechanism for Stablecoin liquidity", + journal = "", + volume = "", + number = "", + pages = "", + year = "2019", + DOI = "https://berkeley-defi.github.io/assets/material/StableSwap.pdf", + keywords = "amm" +} +@article{homotopy, + doi = {10.48550/ARXIV.2203.12123}, + + url = {https://arxiv.org/abs/2203.12123}, + + author = {Port, Alexander and Tiruviluamala, Neelesh}, + + keywords = {Trading and Market Microstructure (q-fin.TR), FOS: Economics and business, FOS: Economics and business, 91B26}, + + title = {Mixing Constant Sum and Constant Product Market Makers}, + + publisher = {arXiv}, + + year = {2022}, + + copyright = {Creative Commons Attribution 4.0 International} +} +@article{universalamm, + author = "Robinson, Dan", + title = "Uniswap v3: The Universal AMM", + journal = "", + volume = "", + number = "", + pages = "", + year = "2021", + DOI = "https://www.paradigm.xyz/2021/06/uniswap-v3-the-universal-amm", + keywords = "amm" +} + +@article{uniswapv2, + author = "Adams, Hayden, and Zinsmeister, Noah and Robinson, Dan", + title = "Uniswap v2 Core", + journal = "", + volume = "", + number = "", + pages = "", + year = "2020", + DOI = "https://uniswap.org/whitepaper.pdf", + keywords = "amm" +} +@article{uniswapv3, + author = "Adams, Hayden, and Keefer, River and Zinsmeister, Noah and Salem, Moody and Robinson, Dan", + title = "Uniswap v3 Core", + journal = "", + volume = "", + number = "", + pages = "", + year = "2022", + DOI = "https://uniswap.org/whitepaper-v3.pdf", + keywords = "amm" +} + +@article{uniswapv3vscurvev2, + author = "Reucassel, Duncan and Ong, Jeremy and 0xDEF1", + title = "Uniswap vs Curve: Which Is the Best DEX?", + journal = "", + volume = "", + number = "", + pages = "", + year = "2022", + DOI = "https://members.delphidigital.io/reports/uniswap-vs-curve-which-is-the-best-dex/#conclusion", + keywords = "amm" +} + + + + + +https://www.bis.org/publ/work955.pdf \ No newline at end of file From 864d164f70e3149323858c62695bc03b7d565e87 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Thu, 13 Feb 2025 08:35:52 -0500 Subject: [PATCH 101/312] try previous checkout action --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bd898e6..27666da 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ jobs: name: Foundry project runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v3 with: submodules: recursive From ce40c1f5e4918ae2e17a7b6a622b8e568be32b13 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Thu, 13 Feb 2025 13:39:26 +0000 Subject: [PATCH 102/312] feat: add disclaimer --- docs/white-paper/main.tex | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/white-paper/main.tex b/docs/white-paper/main.tex index 7ae8c72..8b3649a 100644 --- a/docs/white-paper/main.tex +++ b/docs/white-paper/main.tex @@ -497,3 +497,14 @@ \subsection{Invariant derivation} \geq x_{0}+\frac{p_{y}}{p_{x}}\left(y_{0}-y\right)\left(c_{y}+\left(1-c_{y}\right)\left(\frac{y_{0}}{y}\right)\right). \end{equation} + +\section{Disclaimer} + +This paper is for general information purposes only. It does not constitute investment +advice or a recommendation or solicitation to buy or sell any investment and should not +be used in the evaluation of the merits of making any investment decision. It should not +be relied upon for accounting, legal or tax advice or investment recommendations. This +paper reflects current opinions of the authors and is not made on behalf of Euler Labs or its +affiliates and does not necessarily reflect the opinions of Euler Labs, its affiliates or individuals +associated with Euler Labs. The opinions reflected herein are subject to change without being +updated. \ No newline at end of file From c642fdba0197b0e1ba7e38e90d53194884e596e2 Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Thu, 13 Feb 2025 14:12:08 +0000 Subject: [PATCH 103/312] feat: more concise abstract --- docs/white-paper/main.tex | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/docs/white-paper/main.tex b/docs/white-paper/main.tex index 8b3649a..42bb42f 100644 --- a/docs/white-paper/main.tex +++ b/docs/white-paper/main.tex @@ -39,14 +39,16 @@ \maketitle -\begin{abstract} - Maglev is an Automated Market Maker (AMM) that uses unique features of Euler lending vaults to \textbf{mag}nify capital efficiency using \textbf{lev}erage. By borrowing assets as needed, Maglev AMMs can extend the range of their reserves and earn fees on trades several times larger than their actual liquidity. Under optimal conditions, Maglev can achieve up to 40x the liquidity depth of traditional AMMs. Using the Ethereum Vault Connector (EVC), Maglev enables market makers to efficiently borrow the `out token' of a swap using the `in token' as collateral. This significantly improves liquidity for swappers. A novel and highly customisable AMM curve governs swap exchange rates, ensuring deep just-in-time liquidity in the short term while incentivising balance over longer periods. +\begin{abstract} + Maglev is an Automated Market Maker (AMM) that uses unique features of Euler lending vaults to dramatically \textbf{mag}nify capital efficiency using \textbf{lev}erage. Unlike traditional AMMs that require fragmented liquidity pools, Maglev enables a single, cross-collateralized vault to provide liquidity across multiple asset pairs simultaneously, maximizing capital efficiency and scaling liquidity across DeFi. Using the Ethereum Vault Connector (EVC), Maglev allows market makers to borrow the out token of a swap using the in token as collateral, unlocking deep liquidity without requiring large static deposits. This liquidity-sharing model allows Maglev to achieve up to 40x the liquidity depth of traditional AMMs, efficiently repurposing idle assets for optimal capital utilization. At the core of Maglev is a highly customizable AMM curve that governs swap exchange rates, ensuring deep, just-in-time liquidity while dynamically incentivizing market balance. By combining on-demand borrowing, shared liquidity, and flexible AMM mechanics, Maglev eliminates inefficiencies in existing liquidity provisioning, offering superior depth, reduced costs, and greater control for liquidity providers. \end{abstract} \section{Introduction} Maglev enhances trade execution by increasing the size of swaps that can be serviced compared to traditional AMMs. This is made possible by combining a novel AMM curve with the advanced \href{https://docs.euler.finance/developers/evc/keyConcepts?_highlight=operator#batch-operations}{check deferrals} and \href{https://docs.euler.finance/developers/evc/keyConcepts?_highlight=operator#operators}{operator} features of the Ethereum Vault Connector (EVC). Market makers supply an initial amount of liquidity to a `swap account' which can then be amplified through borrowing. Specifically, when a user swaps an `in token,' Maglev borrows the corresponding `out token,' using the `in token' as collateral. Later, when a swap occurs in the reverse direction, the incoming `in token' repays the outstanding loan, and any excess collateral is returned as the `out token,' effectively closing the position. This leveraged approach significantly increases the available liquidity provided by Maglev and multiplies swap fees. It is somewhat analogous to MEV bots that provide just-in-time single-tick liquidity to Uniswap v3 in order to capture fees on large trades. +Beyond individual swap accounts, Maglev takes capital efficiency further by taking advantage of Euler's modular design to allow multiple swap accounts to be built on top of the same lending vaults. This means that the same idle liquidity inside a single vault can provide depth for swaps across multiple asset pairs simultaneously. Much like Curve’s 3pool, but generalized to any number of asset pairings, a USDC vault could provide deep liquidity for 10+ correlated assets without requiring separate liquidity pools for each. + Maglev’s exchange rates are governed by a highly customisable AMM curve (illustrated in Figure \ref{fig:fig1}) which incentivises swappers to maintain market maker positions in balance over time. The Maglev AMM curve is a novel construction blending constant-sum and constant-product models, allowing swap account creators to tailor their AMM parameters. Like \href{https://berkeley-defi.github.io/assets/material/StableSwap.pdf}{Stableswap}, it supports concentrated liquidity for correlated assets, as well as \href{https://app.uniswap.org/whitepaper.pdf}{Uniswap v2}-style distributed liquidity for uncorrelated pairs. However, unlike those more traditional AMMs, Maglev allows asymmetric liquidity deposits, where different amounts of liquidity can be added to each side of the pool, and single-sided liquidity concentration, enabling deeper concentration of liquidity on one side of the pool relative to the other. This enables it to simulate the behaviour of atypical AMM protocols, like the MakerDAO \href{https://mips.makerdao.com/mips/details/MIP29}{Peg Stability Module} (PSM). For end-users, Maglev functions like a typical Uniswap-style interface. However, behind the scenes, it incorporates advanced mechanisms such as borrowing and repaying, custom pricing curves, and dynamic liquidity provisioning. The main target audience for liquidity providers in Maglev AMMs are professional market makers, token issuers, and other DAOs, whilst the main target audience for swappers are leverage traders on Euler, aggregators, intent solvers, and MEV bots. @@ -327,7 +329,16 @@ \subsubsection{Extending the invariant to Maglev} These conditions together define the valid liquidity states in Maglev, ensuring that the AMM remains balanced while allowing for greater flexibility in liquidity provisioning. +\section{Disclaimer} +This paper is for general information purposes only. It does not constitute investment +advice or a recommendation or solicitation to buy or sell any investment and should not +be used in the evaluation of the merits of making any investment decision. It should not +be relied upon for accounting, legal or tax advice or investment recommendations. This +paper reflects current opinions of the authors and is not made on behalf of Euler Labs or its +affiliates and does not necessarily reflect the opinions of Euler Labs, its affiliates or individuals +associated with Euler Labs. The opinions reflected herein are subject to change without being +updated. \end{document} @@ -498,13 +509,5 @@ \subsection{Invariant derivation} x_{0}+\frac{p_{y}}{p_{x}}\left(y_{0}-y\right)\left(c_{y}+\left(1-c_{y}\right)\left(\frac{y_{0}}{y}\right)\right). \end{equation} -\section{Disclaimer} -This paper is for general information purposes only. It does not constitute investment -advice or a recommendation or solicitation to buy or sell any investment and should not -be used in the evaluation of the merits of making any investment decision. It should not -be relied upon for accounting, legal or tax advice or investment recommendations. This -paper reflects current opinions of the authors and is not made on behalf of Euler Labs or its -affiliates and does not necessarily reflect the opinions of Euler Labs, its affiliates or individuals -associated with Euler Labs. The opinions reflected herein are subject to change without being -updated. \ No newline at end of file + Maglev is an Automated Market Maker (AMM) that uses unique features of Euler lending vaults to \textbf{mag}nify capital efficiency using \textbf{lev}erage. By borrowing assets as needed, Maglev AMMs can extend the range of their reserves and earn fees on trades several times larger than their actual liquidity. Under optimal conditions, Maglev can achieve up to 40x the liquidity depth of traditional AMMs. Using the Ethereum Vault Connector (EVC), Maglev enables market makers to efficiently borrow the `out token' of a swap using the `in token' as collateral. This significantly improves liquidity for swappers. A novel and highly customisable AMM curve governs swap exchange rates, ensuring deep just-in-time liquidity in the short term while incentivising balance over longer periods. All of this is built on Euler lending vaults, where a single cross-collateralised vault can provide liquidity across multiple asset pairs, dramatically scaling liquidity and capital efficiency across DeFi. \ No newline at end of file From aa4711bff4277fe920526a83f482a268554ae9aa Mon Sep 17 00:00:00 2001 From: Michael Bentley Date: Thu, 13 Feb 2025 14:15:39 +0000 Subject: [PATCH 104/312] feat: update white paper pdf --- docs/white-paper/Maglev_White_Paper.pdf | Bin 337375 -> 339532 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/white-paper/Maglev_White_Paper.pdf b/docs/white-paper/Maglev_White_Paper.pdf index f86000f0417acee4f7b01dda82489bfd471c7db4..bfbf7d9f1c11fb3574f5428ee552e503eb991aae 100644 GIT binary patch delta 52159 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