Skip to content

code-423n4/2021-11-nested

Repository files navigation

logo

https://nested.finance

Nested Finance contest details

Introduction

Nested Finance is a decentralized protocol providing customizable financial products in the form of NFTs. The platform allows users to put several digital assets, i.e. ERC20 tokens, inside an NFT (abbreviated as NestedNFT).

Each NestedNFT is backed by underlying assets:

  • Purchased or sold on a decentralized exchange (AMM).
  • Collected/earned after adding liquidity or staking.
  • Exchanged/Minted on a protocol that is not a decentralized exchange.
  • (...)

The main idea is to allow adding modules (operators) to interact with new protocols and enable new assets, without re-deploying.

The tokens are stored on a self-custodian smart contract.

At the end of the creation process, the user receives the NFT which allows to control all underlying assets of the portfolio. Furthermore, we allow users to copy other users’ NestedNFTs. The creator of the initial NestedNFT earns royalties.

Further documentation and details can be found here: https://docs.nested.finance/

Architecture 🏗️

diagram

fee_diagram

Core contracts

Name LOC Purpose
NestedFactory 561 Entry point to the protocol. Holds the business logic. Responsible for interactions with operators (submit orders).
NestedAsset 154 Collection of ERC721 tokens. Called NestedNFT across the codebase.
NestedReserve 70 Holds funds for the user. Transferred from the NestedFactory.
NestedRecords 233 Tracks underlying assets of NestedNFTs. (Amount, NestedReserve).
FeeSplitter 276 Receives payments in ERC20 tokens from the factory when fees are sent. Allows each party to claim the amount they are due.
NestedBuyBacker 121 Pulls tokens from the FeeSplitter, buys back NST tokens on the market, and burns a part of it.

Nested Finance will launch a token (NST). The contract is out of the scope of this audit.

Operators (modularization)

What is an operator?

NestedFactory is the main smart contract, but it can't work without the Operators.

As mentioned in the introduction, we designed the protocol to be modular. We want to be able to interact with any protocol in exchange for an ERC20 token.

So, we had to deal with two issues :

  • How to interact with 5, 10, or 20 protocols without blowing up the bytecode size and having too much logic?
  • How to add new interactions without redeploying the NestedFactory contract?

Our solution is called the "Operator"... A new interaction is a new operator and can be added on the fly. They kind of work like libraries, but since we don't want to redeploy the factory, they are contracts that are called via delegatecall and referenced by the OperatorResolver.

One language

To interact with new operators on the fly, they must speak the same language. Let's define the "interactions" common to all operators: commit and revert.

An operator allows performing a precise action, like "swap my token A for a token B". When we want to perform this action, we will "commit". On the other hand, all the actions in DeFi can be carried out in the opposite direction, like "swap my token B against a token A". When we want to "reverse" an action that we have "committed", we will "revert".

Some examples:

Name Commit Revert
Swap Swap token A for token B Swap token B for token A
Add Liquidity - Swap half of token A for token B.
- Add liquidity to A-B pool.
- Remove liquidity from A-B pool.
- Swap (all) token B for token A.
Liquidity Mining - Swap half of token A for token B.
- Add liquidity to A-B pool.
- Stake LP token (for token C reward).
- Unstake LP Token.
- (optional) Swap token C for token A.
- Remove liquidity from A-B Pool.
- Swap (all) token B for token A.

Storage

Since the operators are called via delegatecall: how can we store/retrieve useful data?
In fact, we cannot trust the Factory to provide all the data, like the address of the protocol. It must be stored and managed by the owner.

When deploying an operator, it will also deploy the storage contract using CREATE2 and transfer the ownership to msgSender().

This way, the operator can retrieve the storage address (without storing it) and get the data.

Diagram

image

Contracts

Name LOC Purpose
OperatorResolver 61 Allows the factory to identify which operator to interact with.
MixinOperatorResolver 67 Abstract contract to load authorized operators in cache (instead of calling OperatorResolver).
ZeroExOperator 77 Performs token swaps through 0x (read more).
ZeroExStorage 20 ZeroExOperator storage contract. Must store the 0x swapTarget.
FlatOperator 41 Handles deposits and withdraws. No interaction with any third parties (read more).

More operators will be added. e.g. CurveOperator or SynthetixOperator

Ownership & Governance

Some functions of the protocol require admin rights (onlyOwner).

The contracts are owned by the TimelockController contract from OpenZeppelin, set with a 7-days delay. This ensures the community has time to review any changes made to the protocol.

The owner of the TimelockController is a three-party multisignature wallet.

During the next phase of the protocol, the ownership will be transferred to a fully decentralized DAO.

Deflationary tokens

The protocol is incompatible with deflationary tokens. In fact, you can add a deflationary token to your portfolio but it can lead to unpredictable behaviors (positive or negative).

We have chosen to manage the tokens with a fixed amount (the input) after considering several solutions.

So, how can we mitigate that ?

We're going to maintain a list of all rebase tokens (source coingecko, which is well maintained) and prevent users from adding them to their portfolio on the platform, as well as showing warnings about any rebase tokens that we wouldn't be able to track.

Main concerns 🤔

Our main concerns are :

  • The modular architecture (Factory => Operator).
  • Protection against malicious calldatas (Order[] calldata _orders).
  • Funds safety in NestedReserve and FeeSplitter.

⚠️ Audits (already completed) ⚠️

Two audits have already been completed by Red4Sec and Peckshield.

Links

Development & Testing

Setup

  • Install Node > 12
  • Install Yarn
  • yarn install
  • Copy .env.example to a new file .env and insert a dummy mnemonic and a mainnet api key

Commands

  • Start a local blockchain yarn run

  • Start a hardhat console yarn console

  • Compile yarn compile

  • Generate typechain files yarn typechain

  • Run tests yarn test

Links

Contact us 📝

Wardens! If you have any questions, please contact us!

Axxe (Smart contract engineer)

  • Telegram : @axxedev
  • Discord : axxe#8561
  • Schedule a call : Calendly

Adrien (CTO)

  • Telegram : @adrienspt
  • Discord : Adrien | Nested Finance#6564
  • Schedule a call : Calendly

Beta access β

If you want to access the beta version of Nested Finance, contact Adrien or Axxe. It can help to better understand the protocol context.

Note : The Beta is running on the v1 (puzzle) of the protocol. The version of this contest is the v2 (lego).

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published