Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
392 commits
Select commit Hold shift + click to select a range
8f0c306
Merge pull request #22 from euler-xyz/gas-improvements
euler-mab Feb 17, 2025
283fa1e
Merge branch 'master' into feat/factory
haythemsellami Feb 17, 2025
bbd8d80
fix
haythemsellami Feb 17, 2025
9e1ab2d
fix
haythemsellami Feb 17, 2025
b945455
Merge pull request #7 from euler-xyz/feat/factory
haythemsellami Feb 17, 2025
5611fa9
TODO
haythemsellami Feb 18, 2025
46cdbf0
use _msgSender()
haythemsellami Feb 18, 2025
96609eb
Merge pull request #24 from euler-xyz/todo-file
hoytech Feb 18, 2025
d13874f
remove factory
haythemsellami Feb 18, 2025
ec46a58
Merge pull request #25 from euler-xyz/remove-factory
haythemsellami Feb 18, 2025
8f0df26
clean
haythemsellami Feb 19, 2025
630d7b8
Merge branch 'master' into feat/factory
haythemsellami Feb 19, 2025
48e8bf6
test
haythemsellami Feb 19, 2025
e414078
feat: add vaults address to poolKey and event
haythemsellami Feb 20, 2025
2cf5493
test
haythemsellami Feb 20, 2025
449beb4
Merge pull request #26 from euler-xyz/feat/factory
euler-mab Feb 22, 2025
10608be
scripts
haythemsellami Feb 24, 2025
38ecefa
update README
haythemsellami Feb 24, 2025
13f2307
update
haythemsellami Feb 24, 2025
f65395f
fix typo
haythemsellami Feb 24, 2025
6e645a8
update
haythemsellami Feb 25, 2025
7847d8d
update
haythemsellami Feb 25, 2025
a3349f2
fix: force approve for incompatible tokens
kasperpawlowski Feb 25, 2025
b09e0c0
Merge branch 'fix-approval' into scripts
haythemsellami Feb 25, 2025
cf2d9c0
Merge pull request #28 from euler-xyz/fix-approval
haythemsellami Feb 25, 2025
c4de78d
Use new derivation for `f`
hoytech Feb 25, 2025
b3dfd85
prevent griefing where attacker front-runs dust transfer to trigger E…
hoytech Feb 25, 2025
8dad69d
Improve `f.md` docs slightly
hoytech Feb 26, 2025
ff22f3b
update
haythemsellami Feb 27, 2025
fbb52e0
feat: use create2 & check operator
haythemsellami Feb 27, 2025
8ed00b2
feat: swapExactIn() & swapExactOut()
haythemsellami Mar 1, 2025
ae9ad30
update natspec
haythemsellami Mar 1, 2025
d33bc26
Update interface
haythemsellami Mar 1, 2025
8df1cc9
refactor: removed un-needed event
haythemsellami Mar 1, 2025
c977e4f
feat: revised white paper
euler-mab Mar 2, 2025
8538a3b
fix: remove old white-paper dir
euler-mab Mar 2, 2025
873c045
feat: add fuzzland audit
euler-mab Mar 2, 2025
d33b6d8
use unchecked math in f() function to improve on-chain quoting effici…
hoytech Feb 28, 2025
3ea2b45
Merge branch 'master' into csec-fixes
hoytech Mar 2, 2025
6292995
Merge pull request #31 from euler-xyz/csec-fixes
euler-mab Mar 2, 2025
95b8206
Merge pull request #30 from euler-xyz/update-periphery
hoytech Mar 2, 2025
5347495
Merge branch 'master' into update-eulerswapfactory
haythemsellami Mar 2, 2025
5c4aae8
fix
haythemsellami Mar 2, 2025
8d74ce3
chore: re-add events
haythemsellami Mar 2, 2025
f75bca9
Merge pull request #29 from euler-xyz/update-eulerswapfactory
haythemsellami Mar 2, 2025
8bc8a77
chore: rename to eulerAccount
haythemsellami Mar 2, 2025
5598c4d
chore: rename to eulerAccount
haythemsellami Mar 2, 2025
987b844
chore: fix typos
haythemsellami Mar 2, 2025
73e57c9
Merge pull request #32 from euler-xyz/chore-rename_to_eulerAccount
Mar 2, 2025
44ae1a0
fix: remove swap account language in architecture.md
euler-mab Mar 2, 2025
9dcaad7
fix: whitepaper link in readme.md
euler-mab Mar 2, 2025
0e0f10a
fix: typo in whitepaper
euler-mab Mar 2, 2025
d3ffcf6
feat: install uniswap v4-core as submodule
euler-mab Mar 3, 2025
642408a
feat: add fInverse() function to periphery
euler-mab Mar 3, 2025
823eeac
feat: add fInverse() test and EulerSwapMock.sol contract
euler-mab Mar 3, 2025
d47ea30
chore: rename mock to harness and forge fmt
euler-mab Mar 3, 2025
99ecaa3
chore: fInverse() external instead of public
euler-mab Mar 3, 2025
08724a9
fix: gitmodules
haythemsellami Mar 3, 2025
045b206
fix: gitmodules
haythemsellami Mar 3, 2025
7d59efa
fix: gitmodules
haythemsellami Mar 3, 2025
da8f2ee
Merge pull request #35 from euler-xyz/fInverse
haythemsellami Mar 3, 2025
4e7aa22
Add pool's address in Swap event
haythemsellami Mar 3, 2025
c7e66df
Merge pull request #36 from euler-xyz/pool-addr-in-event
euler-mab Mar 3, 2025
f558c74
Revert "Add pool's address in Swap event"
haythemsellami Mar 3, 2025
d11e168
Merge pull request #37 from euler-xyz/revert-36-pool-addr-in-event
haythemsellami Mar 3, 2025
b2112f4
use OZ's mulDiv instead of Uniswap's
hoytech Mar 3, 2025
649b5ca
Merge pull request #39 from euler-xyz/oz-muldiv
Mar 3, 2025
b9a146a
docs: update SECURITY.md with vulnerability disclosure policy
erik1o6 Mar 3, 2025
9e67c0c
pass in raw values for initial and current reserves
hoytech Mar 3, 2025
705d4e0
chore: update .gitignore
euler-mab Mar 4, 2025
957d3b6
chore: remove __MACOSX and .DS_Store files
euler-mab Mar 4, 2025
df7ee9b
feat: add detailed event documentation for EulerSwap and EulerSwapFac…
euler-mab Mar 4, 2025
c1e1c25
feat: add errors.md file
euler-mab Mar 4, 2025
398ba38
Check for reserves overflow in verify() function
hoytech Mar 3, 2025
02db36d
periphery: getLimits
hoytech Mar 4, 2025
d6fc4ad
feat: complete boundary analysis docs for f() and fInverse()
euler-mab Mar 4, 2025
1400cc0
feat: add unchecked to fInverse()
euler-mab Mar 4, 2025
c64b5b5
refactor quoting to share logic with getLimits
hoytech Mar 5, 2025
74d4720
Merge pull request #40 from euler-xyz/update-security-md
haythemsellami Mar 5, 2025
1461604
explicitly check for swap amounts being too large (instead of dependi…
hoytech Mar 5, 2025
6323463
Merge pull request #38 from euler-xyz/raw-reserves
haythemsellami Mar 5, 2025
bbfa037
todo
hoytech Mar 5, 2025
a789a30
forge doc
haythemsellami Mar 5, 2025
2fb7b07
factor duplicated approval/permit2 code
hoytech Mar 5, 2025
b4e4b83
Merge branch 'master' into doc-improvements
haythemsellami Mar 5, 2025
6e3c66a
why bother hashing? it's always going to be a short descriptor anyway
hoytech Mar 5, 2025
a0723b7
chore: delete errors.md
haythemsellami Mar 5, 2025
3035a51
chore: remove events.md
haythemsellami Mar 5, 2025
61bdd1e
Merge pull request #41 from euler-xyz/doc-improvements
haythemsellami Mar 5, 2025
bb2a007
optimize isAccountOperatorAuthorized() call
haythemsellami Mar 5, 2025
f49b4fe
optimize .eulerAccount() calls
haythemsellami Mar 5, 2025
56e7400
optimize vault0() & vaulr1() calls
haythemsellami Mar 5, 2025
065cf6c
clean
haythemsellami Mar 5, 2025
6024532
clean
haythemsellami Mar 5, 2025
2c9c24d
clean
haythemsellami Mar 5, 2025
a4ed549
Merge pull request #46 from euler-xyz/limits-review
haythemsellami Mar 5, 2025
3afce5d
Merge branch 'master' into limits
haythemsellami Mar 5, 2025
b7e7c60
fix: test
haythemsellami Mar 5, 2025
67a32cb
Merge pull request #42 from euler-xyz/limits
haythemsellami Mar 5, 2025
1c07209
add natspec
haythemsellami Mar 5, 2025
a42faf6
Merge pull request #44 from euler-xyz/refactor-approval
haythemsellami Mar 5, 2025
fd94190
Merge pull request #45 from euler-xyz/human-readable-curve-identifier
haythemsellami Mar 5, 2025
84d6939
small clean-up and extra validation (chainsecurity finding 5.7)
hoytech Mar 5, 2025
cb362eb
clean
haythemsellami Mar 5, 2025
c2d071e
remove test
haythemsellami Mar 5, 2025
93d836b
Merge pull request #47 from euler-xyz/final-clean
hoytech Mar 5, 2025
54c1af6
correct quoting for exact output swaps when point is above curve (cha…
hoytech Mar 5, 2025
87d5da0
forge install: v4-periphery
saucepoint Mar 6, 2025
bf95e49
building
saucepoint Mar 6, 2025
6b987bf
forge fmt
saucepoint Mar 6, 2025
578f2f9
fix test; added utilities for tests
saucepoint Mar 6, 2025
a510a92
Merge branch 'master' into scripts
haythemsellami Mar 6, 2025
9624a51
update
haythemsellami Mar 6, 2025
15918ec
stub beforeSwap
saucepoint Mar 6, 2025
727d8b1
build out beforeSwap custom curve
saucepoint Mar 7, 2025
0bf1a79
revert virtual
saucepoint Mar 7, 2025
9660bc2
chore: lint
haythemsellami Mar 10, 2025
81796d3
Merge pull request #27 from euler-xyz/scripts
haythemsellami Mar 10, 2025
0c6238c
remove unnecessary verification of equilibrium point, stricter verifi…
hoytech Mar 10, 2025
e44a49a
prevent read-only re-entrancy in getReserves()
hoytech Mar 12, 2025
fcd9fcf
Avoid deposit() method when only repaying, to support borrow-only vaults
hoytech Mar 12, 2025
e3c7a40
Make factory check that vaults are created by EVK factory
hoytech Mar 12, 2025
6d35d87
pass interfaces instead of raw addresses to internal functions
hoytech Mar 12, 2025
12efc8a
typos and docs
hoytech Mar 12, 2025
1ac5728
merge in main; resolve conflict
saucepoint Mar 12, 2025
ccfee96
restore correct constructor param
saucepoint Mar 12, 2025
e30f681
account for poolManager constructor param
saucepoint Mar 12, 2025
4f745c4
wip: setup EulerSwapHook test
saucepoint Mar 12, 2025
6e31cef
assert v4 pool creation
saucepoint Mar 12, 2025
d103a9f
initial test for exact input swap
saucepoint Mar 12, 2025
26ef2a3
wip
saucepoint Mar 15, 2025
c921f07
delete old test
saucepoint Mar 15, 2025
43be08e
move setup to test base
saucepoint Mar 15, 2025
e0bfe0e
increase assertions
saucepoint Mar 15, 2025
128d1cf
Merge pull request #49 from euler-xyz/sauce/v4-exploration/tests
hoytech Mar 17, 2025
bca991e
inline computeQuote from periphery
hoytech Mar 18, 2025
9b6bd10
use computeQuote to get amountIn/amountOut
hoytech Mar 18, 2025
0989f17
clean-up
hoytech Mar 18, 2025
79b7d26
testing fixes
hoytech Mar 18, 2025
4766454
fmt
hoytech Mar 18, 2025
b2285c8
Merge pull request #50 from euler-xyz/v4-computeQuote
saucepoint Mar 18, 2025
95e473f
verify that prepaid input does not have token liquidity issues
saucepoint Mar 21, 2025
62bdbce
fix for when controller enabled but debt is 0
hoytech Mar 21, 2025
8e5915e
Merge branch 'master' into v4-exploration
hoytech Mar 24, 2025
68197e0
reworked router to prepay input
saucepoint Mar 24, 2025
08252c3
cleanup example router
saucepoint Mar 24, 2025
506d101
Merge pull request #51 from euler-xyz/v4-exploration-merge
saucepoint Mar 24, 2025
45501b7
Merge pull request #52 from euler-xyz/minimal-router
hoytech Mar 24, 2025
8e354b9
refactor for swap fee test
saucepoint Mar 25, 2025
f10e7ce
streamline
saucepoint Mar 25, 2025
fe42bcf
reuse declared variable
saucepoint Mar 25, 2025
871bf6a
assert fee and reserves logic
saucepoint Mar 25, 2025
4237afc
unit tests for fee calculations
hoytech Mar 27, 2025
3692902
Merge branch 'master' into v4-exploration
saucepoint Mar 28, 2025
62c743e
Merge branch 'v4-exploration' into swapfee-test
saucepoint Mar 28, 2025
822a54b
forge fmt
saucepoint Mar 28, 2025
7abb85d
add NAV assertion & fix exact out fee math
saucepoint Mar 28, 2025
dd7e843
remove dead function
saucepoint Mar 28, 2025
76c1a3e
Merge pull request #55 from euler-xyz/swapfee-test
hoytech Mar 31, 2025
c7f93de
add eulerswaphook audit note
saucepoint Apr 2, 2025
0637b6f
port over cool stuff from hub
haythemsellami Apr 2, 2025
d6b1d03
natspec
haythemsellami Apr 2, 2025
b728963
more parity
haythemsellami Apr 2, 2025
e5c722b
more tests for 100% coverage
haythemsellami Apr 2, 2025
31923d5
update
haythemsellami Apr 3, 2025
136eacc
clean
haythemsellami Apr 3, 2025
8109224
Merge pull request #57 from euler-xyz/merge-hub
haythemsellami Apr 3, 2025
efe5487
alternate approach for protocol fee collection
hoytech Apr 1, 2025
18b9165
improve and simplify fee split calculation, change feeMultiplier to j…
hoytech Apr 3, 2025
4dc0b07
Merge pull request #56 from euler-xyz/alt-protocol-fee
hoytech Apr 3, 2025
8f5cd1f
Merge branch 'master' into v4-exploration
hoytech Apr 3, 2025
e7776c0
fix conflicts with new fee computation method
hoytech Apr 3, 2025
fce4e34
Merge pull request #48 from euler-xyz/v4-exploration
hoytech Apr 3, 2025
d20ca38
import Michael's search() routine and dependencies
hoytech Apr 7, 2025
f38db55
fix tests, handle error condition
hoytech Apr 7, 2025
36732d1
mega refactor
hoytech Apr 7, 2025
650d4ae
remove todo that will not be done
saucepoint Apr 14, 2025
ef7a7a0
hard code tick spacing to an easy sentinel value
saucepoint Apr 14, 2025
d79342d
add hook address validation; fix test implementation
saucepoint Apr 14, 2025
ba4b294
updated note
saucepoint Apr 14, 2025
40db263
revert on CLAMM liquidity; updated flags
saucepoint Apr 14, 2025
4c757b0
test that v3 CLAMM reverts
saucepoint Apr 14, 2025
503245f
updated audit note
saucepoint Apr 15, 2025
97f1e5c
building with protocol fee owner
saucepoint Apr 15, 2025
f8bedf8
wip testing
saucepoint Apr 15, 2025
01c759d
assertions for protocol fee
saucepoint Apr 15, 2025
9adb695
ensure quotes for 0 amount swaps return exactly 0
hoytech Apr 15, 2025
7829170
finish test harness for protocol fee params
hoytech Apr 16, 2025
519aced
forge fmt
hoytech Apr 16, 2025
9fc8d0f
Merge pull request #59 from euler-xyz/sauce/hook-todo
hoytech Apr 16, 2025
cfc3b95
Merge pull request #62 from euler-xyz/zero-amount-quotes
hoytech Apr 16, 2025
3f2ff64
Merge pull request #60 from euler-xyz/sauce/revert-add-liq
saucepoint Apr 16, 2025
e269474
merge in upstream; fix conflicts
saucepoint Apr 16, 2025
4334265
note invalidated salt
saucepoint Apr 16, 2025
756f79e
Merge pull request #61 from euler-xyz/sauce/protocol-fee-ops
hoytech Apr 16, 2025
7cc4f94
typo
hoytech Apr 16, 2025
1a714a4
re-org
hoytech Apr 16, 2025
2830d60
revert on subsequent initalize
saucepoint Apr 17, 2025
c99a5d6
test revert second initialize
saucepoint Apr 17, 2025
24e5bd5
Merge pull request #63 from euler-xyz/sauce/initialize-once
hoytech Apr 18, 2025
7949345
remove unused variable
hoytech Apr 18, 2025
ddf3614
improve error message when protocol fee is invalid
hoytech Apr 17, 2025
63a7896
test poolManager accessor
hoytech Apr 18, 2025
eebc566
validate proxy addrs are valid hooks, don't bother with the implement…
hoytech Apr 18, 2025
22fd8de
Merge pull request #64 from euler-xyz/validate-proxy-hook-addrs
saucepoint Apr 18, 2025
c624136
add CurveLib test
euler-mab Apr 20, 2025
cd64cb2
add binary search
euler-mab Apr 20, 2025
6a95354
add working fuzz test
euler-mab Apr 21, 2025
f16493d
unchecked to reduce gas on fInverse()
euler-mab Apr 21, 2025
6e4bb6d
update scripts
haythemsellami Apr 22, 2025
8b66dc7
Merge remote-tracking branch 'origin/mega-refactor-curve-gas'
hoytech Apr 23, 2025
c7d7898
fix path
hoytech Apr 23, 2025
c650fad
some dev comments
hoytech Apr 23, 2025
510ccf3
forge fmt
hoytech Apr 23, 2025
0a5fb35
Merge pull request #65 from euler-xyz/update-scripts
hoytech Apr 23, 2025
1a7e7e0
update architecture docs, todo
hoytech Apr 18, 2025
766f2d7
from Michael: helper function to compute the post-swap derivative (ma…
hoytech Apr 23, 2025
dd99196
minor doc edits
hoytech Apr 23, 2025
fb3c1e1
move functions from CurveLib into more appropriate places: new CurveE…
hoytech Apr 24, 2025
5097bb6
remove unused y0, clean-up pre-conditions
hoytech Apr 24, 2025
debf2b7
fix: scale issue in fInverse
euler-mab Apr 25, 2025
453858e
remove binarySearch, since it is now in test dir
hoytech Apr 25, 2025
be43b12
move CurveExtrasLib into test/ for now
hoytech Apr 25, 2025
612bbb1
forge fmt
hoytech Apr 25, 2025
a8cf496
tighten up MAX_QUOTE_ERROR
hoytech Apr 25, 2025
ec30941
test from MiloTruck
hoytech Apr 28, 2025
d568fa0
integrate and expand test
hoytech Apr 28, 2025
3635092
fix issue with multiple uninstalls by using OZ's EnumerableSet library
hoytech Apr 28, 2025
fc9a1ad
test for UnsupportedPair errors
hoytech Apr 28, 2025
644ff6d
fix parameter ordering bug resulting in incorrect quotes
hoytech Apr 28, 2025
c514e81
in fuzz tests, exercise quoteExactOutput() code path
hoytech Apr 28, 2025
ed485c3
test for getHookPermissions
hoytech Apr 28, 2025
533934e
avoid use of assembly in getParams (suggested by @MiloTruck)
hoytech Apr 29, 2025
6b1bdf2
cosmetic fixes identified in audit
hoytech Apr 29, 2025
e093dee
Merge pull request #70 from euler-xyz/cosmetic-fixes
hoytech Apr 29, 2025
59a0f83
combining eulerAccount with salt is no longer necessary
hoytech Apr 29, 2025
1e0402d
forge fmt
hoytech Apr 29, 2025
53271cb
fix: add even stricter checks in fInverse() fuzz test
euler-mab Apr 29, 2025
3d924eb
use safeTransfer when moving protocol fees, for non-compliant tokens
hoytech Apr 29, 2025
ab6f3a7
Merge pull request #73 from euler-xyz/better-fuzz-test
hoytech Apr 29, 2025
9f8d68b
Merge pull request #67 from euler-xyz/fInverse-bugfix
hoytech Apr 29, 2025
17b085d
Merge pull request #74 from euler-xyz/safe-transfer-protocol-fees
hoytech Apr 29, 2025
cd1d8b1
Merge pull request #68 from euler-xyz/missing-test-coverage
hoytech Apr 29, 2025
d6a30a6
Merge pull request #71 from euler-xyz/simplify-salt
hoytech Apr 29, 2025
6e8a8c8
Merge pull request #69 from euler-xyz/simplify-getParams
hoytech Apr 29, 2025
bf3e362
Merge branch 'master' into uninstall-fix
hoytech Apr 29, 2025
c751556
use values() method of EnumerableSet when possible, to make the code …
hoytech Apr 29, 2025
e3b8548
Merge pull request #66 from euler-xyz/uninstall-fix
hoytech Apr 29, 2025
605201e
Constructor sanity check prevented creation of fully one-sided curves…
hoytech Apr 29, 2025
6a621bc
Merge pull request #75 from euler-xyz/one-sided-curves
hoytech Apr 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
name: Foundry project
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
with:
submodules: recursive

Expand All @@ -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
Expand Down
12 changes: 9 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ out/
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/

# Docs
docs/
broadcast/
script/json/out/

# Dotenv file
.env

# Coverage file
lcov.info

# MAC files
.DS_Store
__MACOSX
15 changes: 15 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[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
[submodule "lib/v4-periphery"]
path = lib/v4-periphery
url = https://github.com/uniswap/v4-periphery
101 changes: 62 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,89 @@
## Foundry
# EulerSwap

**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.**
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.

Foundry consists of:
For more information, refer to the [white paper](./docs/whitepaper/EulerSwap_White_Paper.pdf).

- **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.
## Usage

## Documentation
EulerSwap comes with a comprehensive set of tests written in Solidity, which can be executed using Foundry.

https://book.getfoundry.sh/
To install Foundry:

## Usage
```sh
curl -L https://foundry.paradigm.xyz | bash
```

### Build
This will download foundryup. To start Foundry, run:

```shell
$ forge build
```sh
foundryup
```

### Test
To clone the repo:

```shell
$ forge test
```sh
git clone https://github.com/euler-xyz/euler-swap.git && cd euler-swap
```

### Format
## Testing

```shell
$ forge fmt
```
### in `default` mode

### Gas Snapshots
To run the tests in a `default` mode:

```shell
$ forge snapshot
```sh
forge test
```

### Anvil
### in `coverage` mode

```shell
$ anvil
```sh
forge coverage
```

### Deploy
## Smart Contracts Documentation

```shell
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>
```sh
forge doc --serve --port 4000
```

### Cast
## Private Deployment

```shell
$ cast <subcommand>
```
- EulerSwapFactory: 0x04C54FF83e4BC428FD1eDA2f41cdBd583A2e9cF8
- EulerSwapPeriphery: 0x64A8410D7D2ecF3Aaf32b6C3932e4586f3C42ecE

### Help
------

```shell
$ forge --help
$ anvil --help
$ cast --help
```
- EulerSwapFactory: 0xF75548aF02f1928CbE9015985D4Fcbf96d728544
- EulerSwapPeriphery: 0x813D74E832b3d9E9451d8f0E871E877edf2a5A5f
- USDT-USDT pool: 0x2bFED8dBEb8e6226a15300AC77eE9130E52410fE

------ with Uniswap hook contracts (latest)

- EulerSwap implementation: 0x0B8CD42911551882638f4C762A66570e1fAc624f
- EulerSwapFactory: 0x52177559e6430396b9A7E2176Ef33b4e4052D125
- EulerSwapPeriphery: 0x9F27Bc363DB128cdC349CA54671E6Fbe2bE194D0
- USDT-USDT pool: 0x13f627635CD96a2A75c2efBDba979172cAb2E888

## Safety

This software is experimental and is provided "as is" and "as available".

No warranties are provided and no liability will be accepted for any loss incurred through the use of this codebase.

Always include thorough tests when using EulerSwap to ensure it interacts correctly with your code.

## Known limitations

Refer to the [white paper](./docs/whitepaper/EulerSwap_White_Paper.pdf) for a list of known limitations and security considerations.

## Contributing

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

(c) 2024-2025 Euler Labs Ltd.

All rights reserved.
25 changes: 25 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Euler Security Policy

## Vulnerability Disclosure and Bug Bounty

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.

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**: [[email protected]](mailto:[email protected])
- **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)**
19 changes: 19 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
? tighten up getLimits bounds

TESTING

* when exchange rate in vaults != 1
* 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-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)
* 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?
Binary file added audits/eulerswap-audit-report.pdf
Binary file not shown.
116 changes: 116 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# EulerSwap architecture

## Overview

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 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 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.

The above contracts depend on libraries:

* `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.

And some utilities:

* `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.
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.

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 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.

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.

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.

## Initial State

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.

To be as flexible as possible, EulerSwap allows you to specify the **current reserves** when you are instantiating a pool.

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.

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.


## Fees

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

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.

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:

* 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.

In order to correct any desynchronisation, the EulerSwap operator should be uninstalled and a new, updated one installed instead.


## getLimits

Although the virtual reserves specify a hard limit for swaps, there may be other implicit limits that are even lower:

* 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

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

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:

* 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.

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.
Loading