-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add lending protocol example to academy
- Loading branch information
1 parent
461836a
commit ed23827
Showing
36 changed files
with
9,472 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# =nil; DApp Examples | ||
|
||
Welcome to **=nil; DApp Examples**, a collection of example decentralized applications (DApps) built on the **=nil; blockchain**. This repository serves as a hands-on learning resource for developers exploring **=nil;**'s unique architecture, including **sharded smart contract design, asynchronous contract execution, cross-shard messaging, and token interactions**. | ||
|
||
## π Overview | ||
|
||
This repository contains multiple example projects that **demonstrate how to build and interact with =nil;**. Each example walks through different use cases, helping developers understand how to design scalable, efficient, and modular decentralized applications on **=nil;**. | ||
|
||
### π What Makes =nil; Unique? | ||
|
||
- **Sharded Smart Contracts:** Applications are designed to run across multiple contract shards, improving scalability and execution efficiency. | ||
- **Asynchronous Execution:** Contracts can interact across shards asynchronously, reducing bottlenecks and improving performance. | ||
- **Modular Contract Design**: =nil; promotes modularity, enabling developers to split application logic into isolated contracts, which simplifies code maintenance, enhances flexibility, and allows for more robust upgrades over time. | ||
|
||
--- | ||
|
||
## π Included Examples | ||
|
||
### 1οΈβ£ **Lending and Borrowing Protocol** | ||
|
||
- An example application showcasing a decentralized lending platform built on the =nil; blockchain, featuring deposits, borrowing, repayments, and interest calculations. | ||
- Demonstrates cross-shard interactions with different contract modules managing specific tasks across multiple shards. | ||
- Utilizes asynchronous contract execution and various token functionalities to ensure efficient and scalable DeFi operations. | ||
|
||
> More examples will be added over time! | ||
--- | ||
|
||
## π Getting Started | ||
|
||
### β Prerequisites | ||
|
||
Before running the examples, make sure you have: | ||
|
||
- **Node.js** (>=16.x) | ||
- **Hardhat** | ||
- **=nil; testnet RPC endpoint** (Get one [here](https://t.me/NilDevnetTokenBot)) | ||
|
||
### π₯ Installation | ||
|
||
Clone this repository and install dependencies: | ||
|
||
```sh | ||
git clone https://github.com/nilfoundation/nil | ||
cd nil/academy | ||
``` | ||
|
||
### Running an Example | ||
|
||
Each example is contained in its own directory. Navigate to the example you want to run, compile the contracts, and execute the interaction scripts. | ||
|
||
Follow the specific instructions in each exampleβs README. | ||
|
||
## π― What You Will Learn | ||
|
||
By working with these examples, you will gain hands-on experience in: | ||
|
||
- β **Sharded Smart Contract Design:** Learn how to split logic across multiple contracts for efficiency. | ||
- β **Asynchronous Messaging:** Handle cross-shard interactions and optimize contract execution. | ||
- β **Token Handling:** Work with token transactions and related mechanisms. | ||
- β **Building Scalable Applications:** Implement application logic in a modular way. | ||
|
||
--- | ||
|
||
## π€ Contributing | ||
|
||
We welcome contributions from developers! If you'd like to add new examples or improve existing ones, feel free to submit a **Pull Request**. | ||
|
||
### π‘ How to Contribute: | ||
|
||
- Check the **[Issues](https://github.com/NilFoundation/nil/issues)** section for tasks marked as **"dapp-examples"**. | ||
- Review the **[Contribution Guide](https://github.com/NilFoundation/nil/blob/9549a10983af05c63daa26073cfec3e5ab2aa8ab/CONTRIBUTION-GUIDE.md)** for best practices. | ||
- Add features, test cases, or suggest new DeFi or blockchain use cases. | ||
|
||
Every contribution helps make this repository a **better learning resource** for everyone! | ||
|
||
--- | ||
|
||
## π Repository Maintenance | ||
|
||
**This repository is actively maintained.** New examples and updates will be added regularly. Stay tuned for upcoming projects showcasing more advanced **=nil;** features. | ||
|
||
Happy coding! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
NIL_RPC_ENDPOINT=YOUR_RPC_URL | ||
PRIVATE_KEY=YOUR_PRIVATE_KEY | ||
NIL=0x0001111111111111111111111111111111111110 | ||
USDT=0x0001111111111111111111111111111111111113 | ||
ETH=0x0001111111111111111111111111111111111112 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/node_modules | ||
.env | ||
/cache | ||
/typechain-types |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
### **Sharded Lending Protocol on =nil; Foundation** | ||
|
||
**This document is an example and is provided for educational purposes only.** It is not audited, and the implementation described here is not intended for production use. The following guide demonstrates how to implement a decentralized lending and borrowing protocol on **=nil; Foundation** using **sharded smart contract architecture**. The goal is to **illustrate key coding practices**, such as using `sendRequest`, `asyncCall`, `sendRequestWithTokens`, encoding function signatures, and handling `TokenId` as an argument of type `address`. The example should serve as a reference for learning and prototyping. | ||
|
||
--- | ||
|
||
### **Sharded Smart Contract Architecture in DeFi** | ||
|
||
**Sharded smart contract design** involves splitting the logic of a decentralized application (dApp) into multiple, independent contracts, each responsible for specific tasks. These contracts communicate asynchronously, enabling the system to process transactions concurrently and increase scalability. In the context of a decentralized lending protocol, this means dividing the protocolβs functions into separate contracts such as **GlobalLedger**, **InterestManager**, **LendingPool**, and **Oracle**. These contracts are **deployed across different shards** to process tasks in parallel, improving system performance and throughput. | ||
|
||
This example demonstrates how sharded contracts can enhance scalability, efficiency, and maintainability, but note that the code is meant for educational use only. It has not been audited and should not be used in a production environment without thorough review. | ||
|
||
--- | ||
|
||
### **Key Coding Practices for Implementing the Lending Protocol** | ||
|
||
The following section describes best practices used throughout this educational example. We will walk through how to handle key aspects like `TokenId` as `address`, use of `sendRequest` and `asyncCall`, and the importance of correctly encoding function signatures and contexts. | ||
|
||
--- | ||
|
||
#### **1. TokenId as Address** | ||
|
||
In **=nil;**, `TokenId` is an alias for the `address` type. When interacting with other contracts that require `TokenId` as an argument, you must treat `TokenId` as an `address` to ensure compatibility as Solidity only recognizes in-built types. | ||
|
||
**Key Consideration:** | ||
|
||
- **TokenId is treated as an `address`:** Always ensure that `TokenId` is passed as an `address` when encoding, decoding, or interacting with other contracts. | ||
|
||
Example: | ||
|
||
```solidity | ||
function deposit() public payable { | ||
Nil.Token[] memory tokens = Nil.txnTokens(); | ||
bytes memory callData = abi.encodeWithSignature( | ||
"recordDeposit(address,address,uint256)", | ||
msg.sender, | ||
tokens[0].id, // TokenId is treated as address | ||
tokens[0].amount | ||
); | ||
Nil.asyncCall(globalLedger, address(this), 0, callData); | ||
} | ||
``` | ||
|
||
**Best Practice:** | ||
|
||
- When working with `TokenId`, **always treat it as an `address`** in function signatures or contract calls. | ||
- Ensure proper encoding of `TokenId` to prevent errors during cross contract execution. | ||
|
||
--- | ||
|
||
#### **2. Using `sendRequest` and `sendRequestWithTokens`** | ||
|
||
The **`sendRequest`** and **`sendRequestWithTokens`** functions are used to send asynchronous requests to other contracts. These functions are crucial for non-blocking operations, allowing the protocol to continue processing. When the request is processed at the destination contract, a response is sent and the function selector encoded in the `context` is invoked along with the response data. | ||
|
||
Example of using `sendRequest`: | ||
|
||
```solidity | ||
bytes memory callData = abi.encodeWithSignature("getPrice(address)", borrowToken); | ||
bytes memory context = abi.encodeWithSelector( | ||
this.processLoan.selector, msg.sender, amount, borrowToken, collateralToken | ||
); | ||
Nil.sendRequest(oracle, 0, 9_000_000, context, callData); | ||
``` | ||
|
||
**Key Points:** | ||
|
||
- **Function Selectors:** Always use `abi.encodeWithSelector` when creating function selectors to ensure the correct function is called during the callback. | ||
|
||
```solidity | ||
bytes memory context = abi.encodeWithSelector( | ||
this.processLoan.selector, msg.sender, amount, borrowToken, collateralToken | ||
); | ||
``` | ||
|
||
- **Signature Encoding:** The function signature must match exactly, including spaces, capitalization, and parameter types. Even small errors can lead to encoding failures. | ||
|
||
```solidity | ||
bytes memory callData = abi.encodeWithSignature("getPrice(address)", borrowToken); | ||
``` | ||
|
||
**Best Practices:** | ||
|
||
- **Ensure correct encoding of function signatures:** Be cautious about the spacing, capitalization, and parameter ordering. Even a small discrepancy will break the function call. | ||
- Always verify that the `context` you create matches the structure expected by the callback function. Mismatches can cause decoding errors during execution. | ||
|
||
--- | ||
|
||
#### **3. Handling Context and `asyncCall`** | ||
|
||
The **`asyncCall`** function enables asynchronous interactions between contracts. In this example, `asyncCall` is used to record deposit information in the **GlobalLedger** contract while allowing the **LendingPool** contract to continue processing other transactions. The `asyncCall` doesnn't expect a callback and hence is a fire and forget function, where as `sendRequest` discussed above expects a callback. | ||
|
||
Example of using `asyncCall` with context: | ||
|
||
```solidity | ||
bytes memory callData = abi.encodeWithSignature( | ||
"recordDeposit(address,address,uint256)", | ||
msg.sender, | ||
tokens[0].id, // TokenId as address | ||
tokens[0].amount | ||
); | ||
Nil.asyncCall(globalLedger, address(this), 0, callData); | ||
``` | ||
|
||
**Best Practices:** | ||
|
||
- **Context Construction:** Use `abi.encodeWithSignature` or `abi.encode` to build the callData, ensuring it contains all the necessary data for the destination contract's function. | ||
|
||
--- | ||
|
||
#### **4. Be Cautious with Space and Character Sensitivity** | ||
|
||
Solidity is sensitive to even the smallest differences in function signatures, such as spaces or capitalization. This is crucial when working with ABI encoding functions like `abi.encodeWithSignature`. | ||
|
||
**Example of Correct Encoding:** | ||
|
||
```solidity | ||
abi.encodeWithSignature("getPrice(address)", borrowToken) | ||
``` | ||
|
||
**Example of Incorrect Encoding:** | ||
|
||
```solidity | ||
abi.encodeWithSignature("getPrice(address )", borrowToken) // Incorrect due to space after address | ||
``` | ||
|
||
**Best Practices:** | ||
|
||
- **Verify the exact function signature:** Always check that the function signatures used in your contract calls match the exact expected format, including spaces, punctuation, and capitalization. | ||
|
||
--- | ||
|
||
### **Conclusion** | ||
|
||
This guide provides an example implementation of a decentralized lending and borrowing protocol on **=nil; Foundation**, using sharded smart contract architecture. **Please note that this is an educational example only and is not audited for production use.** | ||
|
||
By following the coding practices outlined here, you can better understand how to: | ||
|
||
1. Handle `TokenId` as an `address` when interacting with other contracts. | ||
2. Correctly use `sendRequest` and `asyncCall` for asynchronous contract interactions. | ||
3. Ensure that function signatures and contexts are encoded and decoded properly. | ||
4. Avoid common pitfalls related to character sensitivity in ABI encoding. | ||
|
||
While this example showcases how sharding and asynchronous communication can improve scalability and efficiency, remember that it is intended for learning and prototyping only. If you plan to deploy similar protocols in production, thorough auditing and testing are crucial to ensure security and reliability. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
## π¦ Lending and Borrowing Protocol on =nil; | ||
|
||
## π Overview | ||
|
||
This repository contains an **educational example** of a decentralized application (dApp) showcasing a lending and borrowing protocol built on the **=nil;** blockchain. This example demonstrates how to leverage sharded smart contracts, asynchronous communication, and cross-shard interactions using various methods of `nil.sol`. You can learn how to build on **=nil;** by working through this example. | ||
|
||
### β¨ Features | ||
|
||
- π° **Deposit USDT and ETH** into a lending pool | ||
- π **Borrow assets** based on collateral | ||
- π³ **Repay borrowed assets** seamlessly | ||
- π **Oracle-based price updates** for accurate valuations | ||
|
||
### π Key Highlights | ||
|
||
- 𧩠**Sharded Smart Contracts**: Efficient workload distribution across shards | ||
- β‘ **Asynchronous Communication**: Transaction execution with minimal bottlenecks | ||
- π **Cross-Shard Interactions**: Smart contract coordination across different shards | ||
|
||
--- | ||
|
||
## βοΈ Prerequisites | ||
|
||
Before working with this repository, ensure you have the following installed: | ||
|
||
- π [Node.js](https://nodejs.org/) (version 16 or higher recommended) | ||
- π¦ [npm](https://www.npmjs.com/) (included with Node.js) | ||
- π¨ Hardhat for smart contract development | ||
- π A =nil; testnet RPC endpoint | ||
- π `.env` file with RPC and private key configuration (similar to `.env.example`) | ||
|
||
Check your installed versions with: | ||
|
||
```sh | ||
node -v | ||
npm -v | ||
``` | ||
|
||
--- | ||
|
||
## π¦ Installation | ||
|
||
1. π₯ Clone the repository: | ||
```sh | ||
git clone https://github.com/NilFoundation/nil.git | ||
``` | ||
2. π Navigate to the project root and install dependencies: | ||
```sh | ||
cd nil/academy/lending-protocol | ||
npm install | ||
``` | ||
3. ποΈ **Set up the `.env` file** based on the `.env.example` file: | ||
- Copy `.env.example` to `.env` and update with your RPC endpoint and private key. | ||
```sh | ||
cp .env.example .env | ||
``` | ||
4. ποΈ Compile the smart contracts: | ||
```sh | ||
npx hardhat compile | ||
``` | ||
5. π Run the end-to-end lending workflow: | ||
```sh | ||
npx hardhat run-lending-protocol | ||
``` | ||
This script deploys **contracts across different shards**, sets up accounts, deposits assets, borrows against collateral, and processes repayments. | ||
|
||
--- | ||
|
||
## π Understanding the `run-lending-protocol` Flow | ||
|
||
This command executes the following steps: | ||
|
||
1. π **Deploys contracts** across multiple shards | ||
2. π₯ **Creates smart contract-based accounts** | ||
3. π **Sets and verifies oracle prices** for assets | ||
4. πΈ **Funds accounts with USDT and ETH** | ||
5. π¦ **Deposits funds** into the lending pool | ||
6. π **Initiates borrowing** of ETH against USDT | ||
7. β **Processes loan repayment** | ||
|
||
Check the `Deep-Dive-Into-The-Protocol` for more detailed explanations and coding patterns when building on top of =nil; | ||
|
||
## π€ Contribution | ||
|
||
This project serves as an example, but contributions are welcome to improve and expand its functionality! | ||
|
||
### π‘ How You Can Contribute: | ||
|
||
- βοΈ **Enhance lending mechanisms** and introduce new features | ||
- π **Enable multi token support for lending and borrowing** | ||
- π **Improve cross-shard execution and smart contract interactions** | ||
|
||
π Check out our list of open issues: [Issue](https://github.com/NilFoundation/nil/issues). | ||
π For detailed contribution guidelines, refer to [Contribution Guide](https://github.com/NilFoundation/nil/blob/main/CONTRIBUTION-GUIDE.md) | ||
|
||
π **Thank you for your support, and happy building!** π |
4 changes: 4 additions & 0 deletions
4
.../lending-protocol/artifacts/@nilfoundation/smart-contracts/contracts/Nil.sol/Nil.dbg.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"_format": "hh-sol-dbg-1", | ||
"buildInfo": "../../../../build-info/fb23e4780e5447fac4926540bca38304.json" | ||
} |
Oops, something went wrong.