Euler
Search…
Contract Integration Guide
Find out how to start working with the Euler smart contracts

Modules

The Euler protocol is a collection of smart contracts, connected together with a module system. Each module handles specific areas of the protocol, so depending on what you want to do, you will interact with several different contract addresses.
Some modules are global, for example:
    markets: Activating markets, enter/exiting markets, and querying various market-related information.
    exec: Batch requests, liquidity deferrals (ie, flash loans)
    liquidation: Seizure of assets for users in violation
Other modules are asset-specific:
    eTokens: ERC20-compatible tokens that represent assets
    dTokens: ERC20-compatible tokens that represent liabilities

Deposit and withdraw

In order to invest an asset to earn interest, you need to deposit into an eToken.
1
// Approve the main euler contract to pull your tokens:
2
IERC20(underlying).approve(EULER_MAINNET, type(uint).max);
3
4
// Use the markets module:
5
IEulerMarkets markets = IEulerMarkets(EULER_MAINNET_MARKETS);
6
7
// Get the eToken address using the markets module:
8
IEulerEToken eToken = IEulerEToken(markets.underlyingToEToken(underlying));
9
10
// Deposit 5.25 underlying tokens (assuming 18 decimal places)
11
// The "0" argument refers to the sub-account you are depositing to.
12
eToken.deposit(0, 5.25e18);
13
14
eToken.balanceOf(address(this));
15
// -> internal book-keeping value that doesn't increase over time
16
17
eToken.balanceOfUnderlying(address(this));
18
// -> 5.25e18
19
// ... but check back next block to see it go up (assuming there are borrowers)
20
21
// Later on, withdraw your initial deposit and all earned interest:
22
eToken.withdraw(0, type(uint).max);
Copied!

Borrow and repay

If you would like to borrow an asset, you must have sufficient collateral, and be "entered" into the collateral's market.
1
// Use the markets module:
2
IEulerMarkets markets = IEulerMarkets(EULER_MAINNET_MARKETS);
3
4
// Approve, get eToken addr, and deposit:
5
IERC20(collateral).approve(EULER_MAINNET, type(uint).max);
6
IEulerEToken collateralEToken = IEulerEToken(markets.underlyingToEToken(collateral));
7
collateralEToken.deposit(0, 100e18);
8
9
// Enter the collateral market (collateral's address, *not* the eToken address):
10
markets.enterMarket(0, collateral);
11
12
// Get the dToken address of the borrowed asset:
13
IEulerDToken borrowedDToken = IEulerDToken(markets.underlyingToDToken(borrowed));
14
15
// Borrow 2 tokens (assuming 18 decimal places).
16
// The 2 tokens will be sent to your wallet (ie, address(this)).
17
// This automatically enters you into the borrowed market.
18
borrowedDToken.borrow(0, 2e18);
19
20
borrowedDToken.balanceOf(address(this));
21
// -> 2e18
22
// ... but check back next block to see it go up
23
24
// Later on, to repay the 2 tokens plus interest:
25
IERC20(borrowed).approve(EULER_MAINNET, type(uint).max);
26
borrowedDToken.repay(0, type(uint).max);
Copied!

Flash loans

Euler doesn't have any specific flash loan functionality. Instead, you can defer the liquidity check for your account. The Euler contract will call back into your contract, where you can perform operations like borrow() without worrying about liquidity violations. As long as your callback leaves the account in a non-violating state, the transaction will complete successfully.
Since Euler only charges interest for a loan when it is held for a non-zero amount of time, this results in fee-less flash loans.
Here is an example contract that demonstrates this:
1
contract MyFlashLoanContract {
2
struct MyCallbackData {
3
uint whatever;
4
}
5
6
function somethingThatNeedsFlashLoan() {
7
// Setup whatever data you need
8
MyCallbackData memory data;
9
args.whatever = 1234;
10
11
// Disable the liquidity check for "this" and call-back into onDeferredLiquidityCheck:
12
IExec(exec).deferLiquidityCheck(address(this), abi.encode(data));
13
}
14
15
function onDeferredLiquidityCheck(bytes memory encodedData) external override {
16
MyCallbackData memory data = abi.decode(encodedData, (MyCallbackData));
17
18
// Borrow 10 tokens (assuming 18 decimals):
19
20
IEulerDToken(borrowedDToken).borrow(0, 10e18);
21
22
// ... do whatever you need with the borrowed tokens ...
23
24
// Repay the 10 tokens:
25
26
IERC20(borrowed).approve(EULER_MAINNET, type(uint).max);
27
IEulerDToken(borrowedDToken).repay(0, 10e18);
28
}
29
}
Copied!
encodedData is a pass-through parameter that lets you transfer data to your callback without requiring storage writes.
Last modified 2mo ago