# 合约集成指南

## 模块

Euler协议是通过模块系统连接在一起的智能合约的集合。每个模块处理协议的特定区域，因此根据您想要做什么，您将与几个不同的合约地址进行交互。

一些模块是全局的，例如：

* [markets](https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/kai-fa-zhe/he-yue-can-kao#ieulermarkets)：激活市场，进入/退出市场，查询各种市场相关信息。
* [exec](https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/kai-fa-zhe/he-yue-can-kao#ieulerexec)：批量请求、流动性延期（即闪电贷款）
* [liquidation](https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/kai-fa-zhe/he-yue-can-kao#ieulerliquidation)：扣押违规用户的资产

其他模块是特定用于资产的：

* [eTokens](https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/kai-fa-zhe/he-yue-can-kao#ieuleretoken)：代表资产的 ERC20 兼容代币
* [dTokens](https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/kai-fa-zhe/he-yue-can-kao#ieulerdtoken)：代表负债的 ERC20 兼容代币

## Deposit and withdraw

为了投资资产以赚取利息，您需要“存入”eToken。

```
// Approve the main euler contract to pull your tokens:
IERC20(underlying).approve(EULER_MAINNET, type(uint).max);

// Use the markets module:
IEulerMarkets markets = IEulerMarkets(EULER_MAINNET_MARKETS);

// Get the eToken address using the markets module:
IEulerEToken eToken = IEulerEToken(markets.underlyingToEToken(underlying));

// Deposit 5.25 underlying tokens (assuming 18 decimal places)
// The "0" argument refers to the sub-account you are depositing to.
eToken.deposit(0, 5.25e18);

eToken.balanceOf(address(this));
// -> internal book-keeping value that doesn't increase over time

eToken.balanceOfUnderlying(address(this));
// -> 5.25e18
// ... but check back next block to see it go up (assuming there are borrowers)

// Later on, withdraw your initial deposit and all earned interest:
eToken.withdraw(0, type(uint).max);
```

## 借入和赎回

如果您想借入一项资产，您必须有足够的抵押品，并“进入”抵押品市场。

```
// Use the markets module:
IEulerMarkets markets = IEulerMarkets(EULER_MAINNET_MARKETS);

// Approve, get eToken addr, and deposit:
IERC20(collateral).approve(EULER_MAINNET, type(uint).max);
IEulerEToken collateralEToken = IEulerEToken(markets.underlyingToEToken(collateral));
collateralEToken.deposit(0, 100e18);

// Enter the collateral market (collateral's address, *not* the eToken address):
markets.enterMarket(0, collateral);

// Get the dToken address of the borrowed asset:
IEulerDToken borrowedDToken = IEulerDToken(markets.underlyingToDToken(borrowed));

// Borrow 2 tokens (assuming 18 decimal places).
// The 2 tokens will be sent to your wallet (ie, address(this)).
// This automatically enters you into the borrowed market.
borrowedDToken.borrow(0, 2e18);

borrowedDToken.balanceOf(address(this));
// -> 2e18
// ... but check back next block to see it go up

// Later on, to repay the 2 tokens plus interest:
IERC20(borrowed).approve(EULER_MAINNET, type(uint).max);
borrowedDToken.repay(0, type(uint).max);
```

## 闪电贷

Euler 将闪电贷内置，作为协议的一个组成部分。有两种方法可以进行闪电贷，一种是低级 Euler 特定的方式，另一种是使用 [EIP-3156](https://eips.ethereum.org/EIPS/eip-3156) 兼容的闪电贷适配器。

### 低级闪电贷

进行闪电贷的低级方法是推迟对您账户进行流动性检查。 Euler 合约将回调到您的合约，您可以在其中执行 `borrow()` 之类的操作，而不必担心违反流动性。只要您的回调使账户处于非违规状态，交易就会成功完成。

由于Euler仅在持有非零时间的贷款时才收取利息，这导致了无费用的快速贷款。

这是一个示例合约，可以证明这一点：

```
contract MyFlashLoanContract {
    struct MyCallbackData {
        uint whatever;
    }

    function somethingThatNeedsFlashLoan() {
        // Setup whatever data you need
        MyCallbackData memory data;
        data.whatever = 1234;

        // Disable the liquidity check for "this" and call-back into onDeferredLiquidityCheck:
        IExec(exec).deferLiquidityCheck(address(this), abi.encode(data));
    }

    function onDeferredLiquidityCheck(bytes memory encodedData) external override {
        MyCallbackData memory data = abi.decode(encodedData, (MyCallbackData));

        // Borrow 10 tokens (assuming 18 decimals):

        IEulerDToken(borrowedDToken).borrow(0, 10e18);

        // ... do whatever you need with the borrowed tokens ...

        // Repay the 10 tokens:

        IERC20(borrowed).approve(EULER_MAINNET, type(uint).max);
        IEulerDToken(borrowedDToken).repay(0, 10e18);
    }
}
```

`encodedData` 是一个传递参数，可让您将数据传输到回调，而无需存储写入。

### EIP-3156 闪电贷

还有一个适配器智能合约，将 Euler 的闪贷功能公开为 [EIP-3156](https://eips.ethereum.org/EIPS/eip-3156) 兼容的 API。

智能合约地址为：[mainnet](https://etherscan.io/address/0x07df2ad9878F8797B4055230bbAE5C808b8259b3)、[ropsten](https://ropsten.etherscan.io/address/0x0e60a8406a94787842f07221d2Fb5Bf19856CeA5)。

如何使用适配器的示例可以在 EIP 文档以及 \[Euler 测试套件]\(<https://github.com/euler-xyz/euler-contracts/blob/master/contracts/test/FlashLoanAdaptorTest> .sol)。费用值始终为 0。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/kai-fa-zhe/he-yue-ji-cheng-zhi-nan.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
