# Basin

Basin is a composable EVM-native decentralized exchange protocol that allows for the composition of arbitrary exchange functions, network-native oracles and exchange implementations into a single liquidity pool known as a Well. In practice, Basin lowers the friction for market makers to deploy liquidity with custom orders and allows their liquidity to be used by other network-native protocols without additional trust assumptions.

***

There are numerous risks associated with Basin. Before interacting with Basin, consider reading the [Risks](/risks). If you are interacting with Basin through [Beanstalk](https://bean.money/), consider reading the [Disclosures](https://docs.bean.money/almanac/disclosures) prepared by the Beanstalk DAO.

### Links

* [Introduction](/introduction/why-basin)
* [Components](/components/well)
* [Implementations](/implementations/overview)
* [Other Links](/resources/links)
* [Basin Whitepaper](https://basin.exchange/basin.pdf)
* [Multi Flow Pump Whitepaper](https://basin.exchange/multi-flow-pump.pdf)


# Risks

There are numerous risks associated with Basin. This is not an exhaustive list.

* The Basin code base is novel. None of its components have been tested in the “real world” prior to its initial deployment. The open source nature of Basin means that others can take advantage of any bugs, flaws or deficiencies in it.
* Basin is deployed on the Ethereum and Arbitrum networks. The security of the Ethereum and Arbitrum networks is assumed.
* While Basin and an implementation of each of its components (except Aqueduct, which has not been implemented) have been [audited](/resources/audits) it is no guarantee of security.
* Particularly before the development of an Aqueduct, each component should be verified by users in order to ensure proper functionality.


# Why Basin

Despite the outsized importance of DEX protocols to the permissionless economy, innovation of them has been slow. The primary components of a DEX are:

1. Exchange functions, which specify the conditions under which a given asset can be exchanged for another;
2. Oracles, which save data related to the DEX relevant to other protocols that need to permissionlessly and atomically query the DEX's state; and
3. Exchange implementations, which facilitate the use (i.e., swapping, adding and removing liquidity) of the DEX.

One major problem with current DEX architectures is a lack of composability, such that to add, remove or replace a component of a DEX requires writing an entirely new DEX. This is highly inefficient.

Utility of DEXs has been limited in part because current architectures mandate market makers provide liquidity using a finite set of exchange functions that are provided by the DEX. This limits the flexibility and capital efficiency of market makers' liquidity. Lack of liquidity flexibility and capital efficiency make profitably market making on DEXs excessively difficult. Profitable market making is essential for well functioning liquid markets. **Excessive friction to customizing exchange functions to provide liquidity on DEXs makes it difficult for decentralized permissionless trading environments to compete with centralized permissioned ones in attracting market makers.** A shortage of market makers leads to a shortage of liquidity; a shortage of liquidity leads to a lack of utility for takers.

***

Saving oracle data on a decentralized network is expensive. The only reason to save DEX data in a network-native oracle is so that it can be queried permissionlessly by other network-native protocols. Current DEX architectures mandate using a particular oracle, independent of whether the data saved about the liquidity is being used by other network-native protocols. Because the cost to saving oracle data is passed on to users of the protocol, this policy imposes an often unnecessary cost on all users of the DEX.

In a post-Merge environment, the risk of [oracle manipulation due to inter-block MEV attacks](https://www.alvarorevuelta.com/posts/ethereum-mev-multiblock) has risen dramatically. This has made using existing network-native oracle solutions risky and impractical for protocols that require manipulation resistant oracles. **Upgrading the oracles in existing DEXs to be inter-block MEV resistant is impossible due to the lack of composability between exchange functions and oracles.** As a result, protocols are forced to use non-network-native oracle solutions (i.e., Chainlink) which require additional trust assumptions beyond the integrity of the network itself while users of DEXs are still paying to update useless oracles.

**Basin is an open source permissionless DEX architecture that allows for the composition of arbitrary exchange functions, network-native oracles and exchange implementations into a single liquidity pool known as a Well.** A registry of pool implementations allows for users to verify the accuracy of a pool's use of its exchange function, oracles and exchange implementation. Anyone can deploy new exchange functions, network-native oracles, exchange implementations and registries. Similarly, anyone can deploy a new pool through an existing registry with an exchange function, any (or no) network-native oracles and an exchange implementation included in the registry. In practice, Basin lowers the friction for market makers to deploy liquidity with custom orders and allow their liquidity to be used by other network-native protocols without additional trust assumptions.

***

Well designed open source protocols enable anyone to (1) compose existing components together, (2) develop new components when existing ones fail to meet the needs of users or are cost-inefficient and (3) verify the proper use of existing components in a simple fashion. Basin allows for anyone to compose new and existing (1) [**Well Functions**](/components/well#well-function) (i.e. exchange functions), (2) [**Pumps**](/components/pump) (i.e., network-native oracles) and (3) [**Well Implementations**](/components/well#well-implementation) (i.e., exchange implementations) to create a [**Well**](/components/well) (i.e., a customized liquidity pool). [**Aquifers**](/components/aquifer) (i.e., Well registries) store a mapping from Well addresses to Well Implementations to enable verification of a Well Implementation given a Well address.


# Well

A **Well** allows for the provisioning of liquidity into a single on-chain position that follows arbitrary rules and is represented by an ERC-20 token (i.e., a Well LP Token).

Each Well is defined by:

1. A list of tokens, which contains the set of ERC-20 tokens that the Well supports (i.e., that can be exchanged through, added to, and removed from the Well);
2. A [**Well Function**](#well-function) and its associated data, which defines an invariant relationship between the **Well's Reserves** (i.e., the balances of tokens in (1) at the time of the last supported Well operation) and the supply of Well LP tokens;
3. [**Pumps**](/components/pump) and their associated data, which implement network-native oracles that are updated each time associated Well's Reserves may change;
4. A [**Well Implementation**](#well-implementation), which contains all logic for actions supported by the Well;
5. Optional arbitrary additional data used by the Well; and
6. The [**Aquifer**](/components/aquifer) that deployed the Well.

A Well's state consists of its Reserve balances and Well LP token ownership. Well LP tokens are ERC-20 tokens representing pro-rata ownership of the Well’s Reserves and implement [ERC-2612](https://eips.ethereum.org/EIPS/eip-2612). Well Functions and Pumps can be independently chosen to be stateful or stateless, while Well Implementations are stateful. Including Pumps in a Well is optional.

### Well Function

{% hint style="info" %}
See [IWellFunction.sol](https://github.com/BeanstalkFarms/Basin/blob/master/src/interfaces/IWellFunction.sol).
{% endhint %}

A Well Function defines an invariant relationship between a Well's Reserves and the supply of Well LP tokens. Basin supports Well Functions that contain arbitrary logic. However, Well Functions must be deterministic to be used alongside Pumps. In practice, the handling of arbitrary logic in a Well Function allows for arbitrary order creation (i.e., conditional orders that take network state data as inputs).

### Well Implementation

{% hint style="info" %}
See [IWell.sol](https://github.com/BeanstalkFarms/Basin/blob/master/src/interfaces/IWell.sol).
{% endhint %}

Well Implementations contain all logic to support swapping against, adding liquidity to and removing liquidity from a Well in arbitrary proportions. A Well Implementation may require a Well to have associated data which the implementation uses to properly interface with its Well Function (e.g., an A parameter for a [Curve](https://curve.fi/) style stableswap invariant, a trading fee, etc.) and Pumps (e.g., the look-back period of a Pump). Well Implementations can specify a whitelist (or blacklist) of acceptable (or unacceptable) counterparties and/or liquidity providers.


# Pump

{% hint style="info" %}
See [Pump interfaces](https://github.com/BeanstalkFarms/Basin/tree/master/src/interfaces/pumps).
{% endhint %}

Pumps are a generalized framework for network-native oracles. A Pump is updated upon each interaction with a Well that uses it. A Pump can be shared by multiple Wells if it stores a mapping of Well addresses. Each Pump can determine its own method of recording a Well's Reserves.

When there’s an interaction with a Well, the Well sends two pieces of information to its Pumps: (1) a list of Reserve amounts and (2) additional metadata as a bytestring. Each Pump is responsible for deciding how to weight the new Reserve values relative to the values it had previously and processing the bytestring.

Because storing data on-chain is expensive, only absolutely necessary data should be recorded. Each Well can be deployed with an arbitrary set of Pumps, such that only and exactly the data necessary to satisfy composability between the liquidity in the Well and arbitrary other protocols desired by the liquidity provider is recorded on-chain. Pumps create a minimalist, composable way for liquidity providers to minimize gas costs associated with trading against their liquidity while maximizing customizability for using their liquidity in other protocols.


# Aquifer

{% hint style="info" %}
See [IAquifer.sol](https://github.com/BeanstalkFarms/Basin/blob/master/src/interfaces/IAquifer.sol)
{% endhint %}

Aquifer is an instance of a Well factory (i.e., a permissionless Well deployer and registry). Aquifer deploys Wells by cloning a pre-deployed Well and stores a mapping of the new Well address to the Well Implementation address.

Aquifer creates the first layer of trust for Basin users by providing a way to verify a Well's Implementation given its address. However, users must still verify the authenticity of the Well's Well Function, Pumps and Well Implementation.

***

{% hint style="info" %}
[Aqueduct](https://basin.exchange/basin.pdf#subsection.3.6) is a whitelist of Well Functions, Pumps, Well Implementations and Aquifers. Aqueducts create a single point of trust for users of Basin components. As long as all the components of a Well are included in a trusted Aqueduct, the Well can be trusted. In practice, protocols can deploy an Aqueduct that specifies all the Basin components liquidity providers can (or must) use in order to receive some form of credit from them.\
\
A template Aqueduct has not yet been implemented.
{% endhint %}


# Overview

The following is a list of Basin components that have been implemented and [audited](/resources/audits):

### Constant Product 2 Well Function

See [ConstantProduct2.sol](https://github.com/BeanstalkFarms/Basin/blob/master/src/functions/ConstantProduct2.sol).

### Stable 2 Well Function.

See [Stable2.sol](https://github.com/BeanstalkFarms/Basin/blob/master/src/functions/Stable2.sol).

### Multi Flow Pump

See [Multi Flow Pump](/implementations/multi-flow-pump).

### Well Implementation

See [Well.sol](https://github.com/BeanstalkFarms/Basin/blob/master/src/Well.sol).

### Upgradable Well Implementation

See [WellUpgradeable.sol](https://github.com/BeanstalkFarms/Basin/blob/master/src/WellUpgradeable.sol).

### Aquifer Implementation

See [Aquifer.sol](https://github.com/BeanstalkFarms/Basin/blob/master/src/Aquifer.sol).


# Multi Flow Pump

{% hint style="info" %}
See [MultiFlowPump.sol](https://github.com/BeanstalkFarms/Basin/blob/master/src/pumps/MultiFlowPump.sol).
{% endhint %}

Oracles are a core piece of the decentralized financial tech stack. Non-network-native oracles that require additional trust assumptions beyond the integrity of the network are the only current option for Ethereum-native protocols in a post-Merge environment because current network-native oracles are not resistant to multi-block MEV manipulation.

**Multi Flow** is a multi-block MEV resistant network-native oracle for arbitrary current data in an EVM for both instantaneous and time-weighted values.

Check out the [Multi Flow whitepaper](https://basin.exchange/multi-flow-pump.pdf) for more information and complete formulas.


# Directory

The following guides have step-by-step walkthroughs for connecting to and interacting with Basin and Wells.

### Basics

* [Connect to Basin](/guides/basics/connect-to-basin)
* [Approve Contracts](/guides/basics/approve-contracts)

### Using Wells

* [Add Liquidity](/guides/using-wells/add-liquidity)
* [Remove Liquidity](/guides/using-wells/remove-liquidity)
* [View my Liquidity](/guides/using-wells/view-my-liquidity)
* [Swap](/guides/using-wells/swap)

### Deploy a new Well

* [Deploy a new Well step by step guide](https://github.com/BeanstalkFarms/Basin-Docs/blob/main/guides/deploy-a-well/deploy-well.md)


# Basics

Introductory guides on connecting to and interacting with Basin.

* [Connect to Basin](/guides/basics/connect-to-basin)
* [Approve Contracts](/guides/basics/approve-contracts)


# Connect to Basin

In addition to an internet connection, interacting with Basin requires:

1. A supported Ethereum or Arbitrum wallet with an ETH balance.
   * [Selecting and Funding a Wallet](#selecting-and-funding-a-wallet)
2. Connecting your Ethereum or Arbitrum wallet to Basin.
   * [Connect to Basin with MetaMask - Desktop](#connect-to-basin-with-metamask-desktop)
   * [Connect to Basin with MetaMask - Mobile](#connect-to-basin-with-metamask-mobile)
   * [Connect to Basin with Coinbase Wallet](#connect-to-basin-with-coinbase-wallet)

### **Selecting and Funding a Wallet**

Ethereum and Arbitrum wallets are applications that let you manage your Ethereum or Arbitrum accounts, respectively. Your wallet lets you connect to decentralized applications such as Basin and authorize transactions. On Ethereum and Arbitrum, you are responsible for the security of your own funds. If you are new to decentralized finance, it strongly recommend to research best practices in wallet security before proceeding.

Basin officially supports MetaMask and Coinbase Wallet on desktop and mobile. Although not officially supported, you may be able to connect other wallets such as Brave, Frame or Rabby by selecting MetaMask on [basin.exchange](https://basin.exchange/). WalletConnect is not yet supported.

Some wallets allow purchasing ETH directly within the wallet. Alternatively, send ETH from a cryptocurrency exchange to your wallet address. Make sure both sending and receiving addresses are on the same network.

### **Connect to Basin with MetaMask - Desktop**

**1. Create a MetaMask Wallet**

MetaMask is an Ethereum/Arbitrum wallet that facilitates interaction with the Basin website.

1. Visit [metamask.io/download](https://metamask.io/download/).
2. Select "Install MetaMask For \[your browser]".
3. Select "Add to \[your browser]".
4. Select "Add Extension".
5. Select "Get Started".
6. Follow the instructions to set up your MetaMask wallet. Be sure to save your Secret Recovery Phrase somewhere safe! For better security, use a hardware wallet.
7. In the top right of your browser, click the "Puzzle Piece" icon and then click the "Pin" next to the MetaMask icon to pin MetaMask to your browser toolbar. The MetaMask icon should now appear next to the puzzle piece icon.

**2. Optional: Connect Your Hardware Wallet to MetaMask**

1. Select the MetaMask icon and then click the circle to the right of your MetaMask address.
2. Select "Connect Hardware Wallet".
3. Select your hardware wallet.
4. Select "Connect."
5. Connect and unlock your hardware wallet.
6. Select the wallet address(es) you want to pair with MetaMask.
7. Select "Unlock".

**3. Fund Your MetaMask Wallet with ETH**

This step may be unnecessary if you performed Step 2.

1. Copy your MetaMask Ethereum/Arbitrum wallet address.
2. Send your ETH to your MetaMask wallet address from your current ETH wallet or an exchange.

**4. Connect Your MetaMask Wallet to Basin**

1. Visit [basin.exchange](https://basin.exchange/).
2. Select "Connect Wallet" in the top right of the page.
3. Click the MetaMask icon and confirm that you are on the Ethereum mainnet / Arbitrum network. If not, click the down arrow at the top of the window and click "Ethereum Mainnet" / "Arbitrum".
4. Congratulations, you are now connected to Basin. Double check that your wallet address in the top right of the website is the same as your MetaMask wallet address.

### **Connect to Basin with MetaMask - Mobile**

1. Download MetaMask from the [App Store](https://apps.apple.com/us/app/metamask-blockchain-wallet/id1438144202) or [Google Play](https://play.google.com/store/apps/details?id=io.metamask).
2. Follow the instructions to set up your MetaMask wallet. Be sure to save your Secret Recovery Phrase somewhere safe! For better security, use a hardware wallet.
3. From the menu, select "Browser" and visit [basin.exchange](https://basin.exchange/).
4. Select "Connect Wallet" in the top right of the page and select "MetaMask". Confirm the connection in MetaMask.
5. Congratulations, you are now connected to Basin. You can verify your connection in the hamburger menu.

### **Connect to Basin with Coinbase Wallet**

1. Visit [basin.exchange](https://basin.exchange/).
2. Click “Connect Wallet” in the top right of the page.
3. Click “Coinbase Wallet”.
4. If you are using the Coinbase Wallet mobile app, scan the QR code.

Confirm that you are on the Ethereum mainnet / Arbitrum via the network dropdown in the top right. If so, congratulations, you are now connected to Basin. Double check that your wallet address in the top right of the website is the same as your Coinbase Wallet address.


# Approve Contracts

Certain transactions require approving certain smart contracts to process your transaction. When a mode is selected that requires an approval, if you have not yet approved the contract, a special notice will appear and the module will be unusable until you send an approve.

To send an approval for the transaction in question:

1. Select "Approve \[Token]".
2. Confirm the transaction in your wallet and your hardware wallet, if applicable. You should verify that the transaction is interacting with the [correct contract](/resources/contracts) before signing it.


# Using Wells

Guides on interacting with [Wells](/components/well).

* [Add Liquidity](/guides/using-wells/add-liquidity)
* [Remove Liquidity](/guides/using-wells/remove-liquidity)
* [View my Liquidity](/guides/using-wells/view-my-liquidity)
* [Swap](/guides/using-wells/swap)


# Add Liquidity

1. Make sure you are on [basin.exchange](https://basin.exchange/) and [connect your wallet](/guides/basics/connect-to-basin).
2. Navigate to the “Liquidity” page. The "View Wells" tab shows available Wells.&#x20;
3. Select the Well and select "Add/Rm Liquidity".
4. Under "Add Liquidity", input the quantity of each token you want to add in exchange for LP tokens.
   * If you have both tokens, you can select "Add tokens in balanced proportion" to add an equal dollar value of each token.
   * If you are adding only one token, your transaction will have a price impact on the Well.
5. A transaction preview including price impact can be viewed by expanding the "Expected Output" toggle.
6. You may select a slippage tolerance by selecting the gear icon under "Expected Output". The default slippage tolerance is 0.1%.
7. If you are adding ETH or have previously approved the asset being spent, skip to Step 9. For all other assets, select “Approve \[Token]”. This allows the Basin contract to spend the asset, but does not add liquidity yet.
8. Confirm the approval transaction in your wallet, and your hardware wallet, if applicable. You should verify that the transaction is interacting with the [correct contract](/resources/contracts) before signing it.
9. Select “Add Liquidity”.
10. Confirm the transaction in your wallet and your hardware wallet, if applicable. You should verify that the transaction is interacting with the [correct contract](/resources/contracts) before signing it.
11. After the transaction has been confirmed by the network, view your liquidity by navigating to the "Liquidity" page and selecting "My Liquidity Positions".


# Remove Liquidity

1. Make sure you are on [basin.exchange](https://basin.exchange/) and [connect your wallet](/guides/basics/connect-to-basin).
2. Navigate to the “Liquidity” page. Under the "My Liquidity Positions" tab, select the Well from which you want to remove liquidity.
3. Select "Add/Rm Liquidity" then "Remove Liquidity".
4. Input the quantity of LP tokens you would like to remove.
   * You can receive one token in the Well by selecting "Single Token" or both tokens by selecting "Multiple Tokens".
   * If you select "Multiple Tokens", selecting "Claim in balanced proportion" will return an equal dollar value of each token.
   * If you select "Single Token", or "Multiple Tokens" and do not "Claim in balanced proportion", your transaction will have a price impact on the Well.
5. A transaction preview including price impact can be viewed by expanding the "Expected Output" toggle.
6. You may select a slippage tolerance by selecting the gear icon under "Expected Output". The default slippage tolerance is 0.1%.
7. If you have previously approved the LP tokens, skip to Step 9. Otherwise, select “Approve \[Token]”. This allows the Basin contract to spend the LP token, but does not remove liquidity yet.
8. Confirm the approval transaction in your wallet, and your hardware wallet, if applicable. You should verify that the transaction is interacting with the [correct contract](/resources/contracts) before signing it.
9. Select “Remove Liquidity”.
10. Confirm the transaction in your wallet and your hardware wallet, if applicable. You should verify that the transaction is interacting with the [correct contract](/resources/contracts) before signing it.
11. After the transaction has been confirmed by the network, your tokens will be in your wallet.


# View my Liquidity

1. Make sure you are on [basin.exchange](https://basin.exchange/) and [connect your wallet](/guides/basics/connect-to-basin).
2. Navigate to the “Liquidity” page and select the "My Liquidity Positions" tab.
3. Your liquidity positions will be listed by Well.
   * By selecting the Well where you have LP tokens, you can view whether the LP tokens are [Deposited in the Silo](https://docs.bean.money/almanac/farm/silo) (if the Well is on the Deposit Whitelist) or [remove your liquidity](/guides/using-wells/remove-liquidity).


# Swap

Tokens in Wells can be bought and sold on the [Swap](https://basin.exchange/#/swap) page.

1. Make sure you are on [basin.exchange](https://basin.exchange/) and [connect your wallet](/guides/basics/connect-to-basin).
2. Navigate to the “Swap” page.
3. In the first field select the input token, or the asset you would like to sell. The dropdown menu will show each available input token and the total balance in your wallet.
4. In the second field, select the output token, or the asset you would like to buy.
5. Enter the amount of the input token to sell, up to the amount in your wallet.
6. Verify the amount of the output token you will receive in the output field.
7. A transaction preview will appear below the inputs. Select the “Minimum Output” dropdown to review each step of the transaction.
8. You may select a slippage tolerance by selecting the gear icon under "Minimum Output". The default slippage tolerance is 0.1%.
9. If you are trading ETH or have previously approved the token being spent, skip to Step 11. For all other tokens, select “Approve \[Token]”. This allows the Basin contract to spend the token, but does not execute the trade yet.
10. Confirm the approval transaction in your wallet, and your hardware wallet, if applicable. You should verify that the transaction is interacting with the [correct contract](/resources/contracts) before signing it.
11. Select “Swap”.
12. Confirm the transaction in your wallet and your hardware wallet, if applicable. You should verify that the transaction is interacting with the [correct contract](/resources/contracts) before signing it.
13. After the transaction has been confirmed by the network, your tokens will be in your wallet.


# Deploying Wells

Guides on deploying [Wells](/components/well).

* [Deploy a Well](/guides/deploying-wells/deploy-a-well)


# Deploy a Well

{% hint style="info" %}
See <https://basin.exchange/#/build> to instead to deploy a Well using the Basin UI.
{% endhint %}

Basin is a composable DEX protocol, meaning that it has various modular components that can be composed together to create new liquidity pools. These components are [Well Functions](/components/well#well-function), [Well implementations](/components/well#well-implementation) and network-native oracles known as [Pumps](/components/pump).

The simplest way for someone to deploy a new Well is by calling the `boreWell` function on the [Aquifer](/components/aquifer) (factory) contract. `boreWell` accepts the encoded addresses of each Well component as input, along with additional parameters such as the Well's name and symbol and a salt for deterministic address generation. It then verifies that the calldata is valid and clones a pre-deployed Well template with the new parameters. In addition, a mapping of the new Well address to the existing Well Implementation address is stored in the Aquifer contract.

#### Well Deployer CLI Tool

To reduce complexity and combine the steps below, you can use the CLI tool found on the Beanstak Farms GitHub repository [here](https://github.com/BeanstalkFarms/Basin-Well-Deployer) with instructions on how to use it. If you have any questions or need help using the CLI tool, feel free to reach out on the official Basin [Discord](https://basin.exchange/discord). Otherwise, you can follow the steps detailed below.

### Step by step guide to deploy a new Well

#### 1. Obtain the addresses of the components to be used in the new Well.

First, obtain the addresses of the 2 ERC-20 tokens to be traded in the new Well. You can find a number of tokens and their addresses on [Etherscan](https://etherscan.io/tokens) or any other block explorer.

Next, obtain the addresses for the desired Well Function, Well Implementation and Pump. You can find the addresses for audited and deployed Well components [here](/resources/contracts).

Finally, decide on a Well name and symbol. These can be any string of your choice but it is recommended to follow the standard format.

* The standard name format is `tokenSymbol1:tokenSymbol2 + Well Function name + "Well"`. For example assuming you are creating a well for the tokens wETH and wBTC with a Constant Product 2 function, the name would be `wETH:wBTC Constant Product 2 well`.
* The standard symbol format is `tokenSymbol1 + tokenSymbol2 + Well Function abbreviation + "w"`. For example assuming you are creating a Well for the tokens wETH and wBTC with the Constant Product 2 Well function, the symbol would be `wETHwBTCCP2w`.

#### 2. Encode the calldata

After getting the necessary parameters described above for the new Well, you will need to properly encode them for the Aquifer contract. There are 2 parts of calldata that need to be encoded. The first is the `init` function call on the Well Implementation contract, to initialize the new Well with the name and symbol. The second is the immutable data of the well, which includes the addresses of the tokens, the Pump and the Well Function. These 2 parts should be encoded separately by using the `abi.encodePacked` function in Solidity or the alternative `ethers.solidityPacked` in JavaScript using the `ethers` library.

Here is an example of how to encode the data using `ethers.js` starting with the `init` function call. To obtain the Well Implementation ABI, you can take a look at the verified Well Implementation contracts on [Etherscan](https://etherscan.io/address/0xBA510e11eEb387fad877812108a3406CA3f43a4B#code).

```javascript
async function encodeInitFunctionCall(wellImplementationAbi, wellName, wellSymbol) {
    const wellInterface = new hre.ethers.Interface(wellImplementationAbi)
                                          // function   name,  symbol     
    return wellInterface.encodeFunctionData('init', [wellName, wellSymbol]);
}

// Example usage
const wellImplementationAbi = "<ABI-FROM-ETHERSCAN>";
const wellName = "wETH:wBTC Constant Product 2 well";
const wellSymbol = "wETHwBTCCP2w";
const initFunctionCall = await encodeInitFunctionCall(wellImplementationAbi, wellName, wellSymbol);
```

Here is an example of how to encode the immutable data of the Well:

```javascript
function encodeWellImmutableData(
    aquifer,
    tokens,
    wellFunction,
    pumps
  ) {
    let packedPumps = '0x';
    for (let i = 0; i < pumps.length; i++) {
        packedPumps = hre.ethers.solidityPacked(
            ['bytes', 'address', 'uint256', 'bytes'],
            [
                packedPumps,           // previously packed pumps
                pumps[i].target,       // pump address
                pumps[i].length,       // pump data length
                pumps[i].data          // pump data (bytes)
            ]
        )
    }
  
  
    immutableData = hre.ethers.solidityPacked(
        [
            'address',                  // aquifer address
            'uint256',                  // number of tokens
            'address',                  // well function address
            'uint256',                  // well function data length
            'uint256',                  // number of pumps
            'address[]',                // tokens array
            'bytes',                    // well function data (bytes)
            'bytes'                     // packed pumps (bytes)
        ], [
        aquifer,                    // aquifer address
        tokens.length,              // number of tokens
        wellFunction.target,        // well function address
        wellFunction.length,        // well function data length
        pumps.length,               // number of pumps
        tokens,                     // tokens array
        wellFunction.data,          // well function data (bytes)
        packedPumps                 // packed pumps (bytes)
    ]
    );
    return immutableData
  }

// Example usage
// Aquifer address on mainnet
const aquifer = "0xBA51AAAA95aeEFc1292515b36D86C51dC7877773"; 
// Well function and pump addresses on mainnet
const wellFunctionAddress = "0xBA510C20FD2c52E4cb0d23CFC3cCD092F9165a6E";
const pumpAddress = "0xBA510f10E3095B83a0F33aa9ad2544E22570a87C";
// Token addresses
// wBTC
const token1 = "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599";
// wETH
const token2 = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
const tokens = [token1, token2];
const wellFunction = { target: wellFunctionAddress, data: '0x', length: 0 }; // well function
const pumps = [{ target: pumpAddress, data: '0x', length: 0 }]; // pumps
const immutableData = encodeWellImmutableData(aquifer, tokens, wellFunction, pumps);
```

The final calldata from the above examples will look something like this:

```bash
Encoded Immutable Data:  0x7aa056fcef8f529e8c8e0732727f40748f49bc1b000000000000000000000000000000000000000000000000000000000000000230af8bc21683754086cdcb27c828facae85cbcad000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000003f4b6664338f23d2397c953f2ab4ce8031663f800000000000000000000000007aaaa3d35497291e85f9b3673498afc8fb8381479a3ae9143753efc2cc9583eb03defac75b6496860000000000000000000000000000000000000000000000000000000000000000

Encoded Init Data: 
0x7029144c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000224f4b423a57535445544820436f6e7374616e742050726f6475637420322057656c6c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d4f4b425753544554484350327700000000000000000000000000000000000000
```

#### 3. Choose a salt for deterministic address generation.

The `salt` is an additional parameter thats used to calculate the address of the deployed well. This allows it to be deployed on different EVM chains and have the same deterministic address, as long it uses the same salt. It also allows for the creation of vanity addresses by mining for a salt value that gives the wanted address. The salt is optional and can be any 32 byte value. It is recommended to use a random value for the salt to know the exact address of new Well before deploying it.

#### 4. Call the boreWell function on the Aquifer contract with the encoded data as parameters.

You are now ready to call the `boreWell` function on the Aquifer contract with the encoded data as the parameter! The call would look something like this in JavaScript:

```javascript
  await deployedAquifier.boreWell(
    wellImplementationAddress,
    immutableData,
    initData,
    salt
  );
```

Congratulations! You have now deployed a new Well on Basin. The new Well will be deployed at the address returned by the `boreWell` function. You can now use the new Well to provide liquidity and trade tokens.

**Important Notes**

All of the above can be achieved only assuming all the required components used in the new Well are already deployed. Thorough verification of the components is required beforehand to ensure the Well is deployed correctly. You can find the addresses for audited and deployed versions of each Well component [here](/resources/contracts).


# Contracts

## Arbitrum

### Basin on Arbitrum

<table><thead><tr><th width="214">Contract</th><th>Arbitrum Address</th></tr></thead><tbody><tr><td>Aquifer</td><td><a href="https://arbiscan.io/address/0xBA51AAAa8C2f911AE672e783707Ceb2dA6E97521">0xBA51AAAa8C2f911AE672e783707Ceb2dA6E97521</a></td></tr><tr><td>Constant Product 2 Well Function</td><td><a href="https://arbiscan.io/address/0xBA15000450Bf6d48ec50BD6327A9403E401b72b4#internaltx">0xBA15000450Bf6d48ec50BD6327A9403E401b72b4</a></td></tr><tr><td>Stable 2 Well Function</td><td><a href="https://arbiscan.io/address/0xba150052e11591D0648b17A0E608511874921CBC">0xba150052e11591D0648b17A0E608511874921CBC</a></td></tr><tr><td>Stable 2 Lookup Table with A = 1</td><td><a href="https://arbiscan.io/address/0xBA51055dAD14d3920e1798D2e8A152d91CaDb461">0xBA51055dAD14d3920e1798D2e8A152d91CaDb461</a></td></tr><tr><td>Multi Flow Pump</td><td><a href="https://arbiscan.io/address/0xBA150002660BbCA20675D1C1535Cd76C98A95b13">0xBA150002660BbCA20675D1C1535Cd76C98A95b13</a></td></tr><tr><td>Well Implementation</td><td><a href="https://arbiscan.io/address/0xBA5106bd62b342afAcB93f1078fe60177A62d1a9">0xBA5106bd62b342afAcB93f1078fe60177A62d1a9</a></td></tr><tr><td>Upgradable Well</td><td><a href="https://arbiscan.io/address/0xBA510995783111be5301d93CCfD5dE4e3B28e50B">0xBA510995783111be5301d93CCfD5dE4e3B28e50B</a></td></tr></tbody></table>

### Whitelisted Beanstalk Wells

<table><thead><tr><th width="214">Contract</th><th>Arbitrum Address</th></tr></thead><tbody><tr><td>BEAN:WETH Well</td><td><a href="https://arbiscan.io/address/0xBeA00Aa8130aCaD047E137ec68693C005f8736Ce">0xBeA00Aa8130aCaD047E137ec68693C005f8736Ce</a></td></tr><tr><td>BEAN:wstETH Well</td><td><a href="https://arbiscan.io/address/0xBEa00BbE8b5da39a3F57824a1a13Ec2a8848D74F">0xBEa00BbE8b5da39a3F57824a1a13Ec2a8848D74F</a></td></tr><tr><td>BEAN:weETH Well</td><td><a href="https://arbiscan.io/address/0xBeA00Cc9F93E9a8aC0DFdfF2D64Ba38eb9C2e48c">0xBeA00Cc9F93E9a8aC0DFdfF2D64Ba38eb9C2e48c</a></td></tr><tr><td>BEAN:WBTC Well</td><td><a href="https://arbiscan.io/address/0xBea00DDe4b34ACDcB1a30442bD2B39CA8Be1b09c">0xBea00DDe4b34ACDcB1a30442bD2B39CA8Be1b09c</a></td></tr><tr><td>BEAN:USDC Well</td><td><a href="https://arbiscan.io/address/0xBea00ee04D8289aEd04f92EA122a96dC76A91bd7">0xBea00ee04D8289aEd04f92EA122a96dC76A91bd7</a></td></tr><tr><td>BEAN:USDT Well</td><td><a href="https://arbiscan.io/address/0xbEA00fF437ca7E8354B174339643B4d1814bED33">0xbEA00fF437ca7E8354B174339643B4d1814bED33</a></td></tr></tbody></table>

### Tokens on Arbitrum

<table><thead><tr><th width="214">Contract</th><th>Arbitrum Address</th></tr></thead><tbody><tr><td>Bean</td><td><a href="https://arbiscan.io/address/0xBEA0005B8599265D41256905A9B3073D397812E4">0xBEA0005B8599265D41256905A9B3073D397812E4</a></td></tr><tr><td>WETH</td><td><a href="https://arbiscan.io/address/0x82aF49447D8a07e3bd95BD0d56f35241523fBab1">0x82aF49447D8a07e3bd95BD0d56f35241523fBab1</a></td></tr><tr><td>wstETH</td><td><a href="https://arbiscan.io/address/0x5979D7b546E38E414F7E9822514be443A4800529">0x5979D7b546E38E414F7E9822514be443A4800529</a></td></tr><tr><td>WBTC</td><td><a href="https://arbiscan.io/address/0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f">0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f</a></td></tr><tr><td>USDC</td><td><a href="https://arbiscan.io/address/0xaf88d065e77c8cC2239327C5EDb3A432268e5831">0xaf88d065e77c8cC2239327C5EDb3A432268e5831</a></td></tr><tr><td>USDT</td><td><a href="https://arbiscan.io/address/0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9">0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9</a></td></tr></tbody></table>

### Ecosystem on Arbitrum

<table><thead><tr><th width="214">Contract</th><th>Arbitrum Address</th></tr></thead><tbody><tr><td>Pipeline</td><td><a href="https://arbiscan.io/address/0xb1bE000644bD25996b0d9C2F7a6D6BA3954c91B0">0xb1bE000644bD25996b0d9C2F7a6D6BA3954c91B0</a></td></tr><tr><td>Depot</td><td><a href=" https://arbiscan.io/address/0xdeb0f082ed3b0efe9257aea9f2e6e974aa4120c3#code">0xdeb0f082ed3b0efe9257aea9f2e6e974aa4120c3</a></td></tr><tr><td>Beanstalk</td><td>See <a href="https://docs.bean.money/almanac/protocol/contracts">Beanstalk docs</a></td></tr></tbody></table>

***

## Ethereum L1

### Basin on L1

<table><thead><tr><th width="214">Contract</th><th>L1 Address</th></tr></thead><tbody><tr><td>Aquifer</td><td><a href="https://etherscan.io/address/0xBA51AAAA95aeEFc1292515b36D86C51dC7877773">0xBA51AAAA95aeEFc1292515b36D86C51dC7877773</a></td></tr><tr><td>Constant Product 2 Well Function v1.0</td><td><a href="https://etherscan.io/address/0xBA510C20FD2c52E4cb0d23CFC3cCD092F9165a6E">0xBA510C20FD2c52E4cb0d23CFC3cCD092F9165a6E</a></td></tr><tr><td>Constant Product 2 Well Function v1.1</td><td><a href="https://etherscan.io/address/0xBA150C2ae0f8450D4B832beeFa3338d4b5982d26">0xBA150C2ae0f8450D4B832beeFa3338d4b5982d26</a></td></tr><tr><td>Multi Flow Pump v1.0</td><td><a href="https://etherscan.io/address/0xBA510f10E3095B83a0F33aa9ad2544E22570a87C">0xBA510f10E3095B83a0F33aa9ad2544E22570a87C</a></td></tr><tr><td>Multi Flow Pump v1.1</td><td><a href="https://etherscan.io/address/0xBA51AaaAa95bA1d5efB3cB1A3f50a09165315A17">0xBA51AaaAa95bA1d5efB3cB1A3f50a09165315A17</a></td></tr><tr><td>Well Implementation</td><td><a href="https://etherscan.io/address/0xBA510e11eEb387fad877812108a3406CA3f43a4B">0xBA510e11eEb387fad877812108a3406CA3f43a4B</a></td></tr></tbody></table>

### Previously Whitelisted Beanstalk Wells on L1

<table><thead><tr><th width="214">Contract</th><th>L1 Address</th></tr></thead><tbody><tr><td>BEAN:WETH Well</td><td><a href="https://etherscan.io/address/0xBEA0e11282e2bB5893bEcE110cF199501e872bAd">0xBEA0e11282e2bB5893bEcE110cF199501e872bAd</a></td></tr><tr><td>BEAN:wstETH Well</td><td><a href="https://etherscan.io/address/0xbea0000113b0d182f4064c86b71c315389e4715d">0xbea0000113b0d182f4064c86b71c315389e4715d</a></td></tr></tbody></table>

### Tokens on L1

<table><thead><tr><th width="214">Contract</th><th>L1 Address</th></tr></thead><tbody><tr><td>Bean</td><td><a href="https://etherscan.io/address/0xBEA0000029AD1c77D3d5D23Ba2D8893dB9d1Efab">0xBEA0000029AD1c77D3d5D23Ba2D8893dB9d1Efab</a></td></tr><tr><td>WETH</td><td><a href="https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2">0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2</a></td></tr><tr><td>wstETH</td><td><a href="https://etherscan.io/address/0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0">0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0</a></td></tr></tbody></table>

### Ecosystem on L1

<table><thead><tr><th width="214">Contract</th><th>L1 Address</th></tr></thead><tbody><tr><td>Pipeline</td><td><a href="https://etherscan.io/address/0xb1bE0000C6B3C62749b5F0c92480146452D15423">0xb1bE0000C6B3C62749b5F0c92480146452D15423</a></td></tr><tr><td>Depot</td><td><a href="https://etherscan.io/address/0xDEb0f00071497a5cc9b4A6B96068277e57A82Ae2">0xDEb0f00071497a5cc9b4A6B96068277e57A82Ae2</a></td></tr></tbody></table>


# Audits

{% hint style="info" %}
Audits of *Basin* refer to the Well Implementation, Constant Product Well Function, Multi Flow Pump, Aquifer implementation, etc. in the [Basin GitHub repository](https://github.com/BeanstalkFarms/Basin) unless otherwise noted.
{% endhint %}

[Code4rena](https://code4rena.com) completed its audit of the [Stable 2 Well Function and Upgradable Well](https://code4rena.com/reports/2024-07-basin) on **September 3, 2024**, identifying 9 findings that were solved or acknowledged prior to deployment. The final report can be found [here](https://bean.money/09-03-24-basin-code4rena-report). The fix review can be found [here](https://bean.money/09-11-24-basin-code4rena-fix-review-report).

[Codehawks](https://codehawks.cyfrin.io) completed its audit of [Multi Flow v1.1](https://codehawks.cyfrin.io/c/2024-04-Beanstalk-DIB/results?lt=contest\&page=1\&sc=reward\&sj=reward\&t=report) on **May 8, 2024**, identifying 4 findings that were solved or acknowledged prior to deployment. The final report can be found [here](https://bean.money/05-08-24-multi-flow-codehawks-report).

Code4rena completed its audit of [Basin](https://code4rena.com/contests/2023-07-basin) on **July 10, 2023**, identifying 28 findings that were solved or acknowledged prior to the deployment of Basin and its components. The final report can be found [here](https://bean.money/10-05-23-basin-code4rena-report).

[Cyfrin](https://www.cyfrin.io/) completed its audit of [Basin](https://github.com/BeanstalkFarms/Beanstalk-Audits/blob/main/ecosystem/06-16-23-basin-cyfrin-report.pdf) on **June 16, 2023**, identifying 29 findings that were solved or acknowledged prior to the release of the report. The final report can be found [here](https://bean.money/06-16-23-basin-cyfrin-report).

[Halborn](https://halborn.com/) completed its audit of [Basin](https://github.com/BeanstalkFarms/Beanstalk-Audits/blob/main/ecosystem/06-16-23-basin-halborn-report.pdf) on **June 16, 2023**, identifying 10 findings that were solved or acknowledged prior to the release of the report. The final report can be found [here](https://bean.money/06-16-23-basin-halborn-report).


# Bug Bounty

The Beanstalk DAO launched a bug bounty program with Immunefi was launched on October 11, 2022.

Basin and its components have been added as in-scope of the program. This bug bounty program is focused on the [Beanstalk](https://bean.money/), Basin and [Pipeline](https://evmpipeline.org/) smart contracts and preventing the loss of user funds. The maximum bounty is **1,100,000 Beans**.

You can find the bug bounty program and submit bug reports [here](https://immunefi.com/bounty/beanstalk):

{% embed url="<https://immunefi.com/bounty/beanstalk/>" %}

In order to be considered for the maximum potential reward, bug reports must come with (1) a Proof of Concept (PoC), and (2) code implementing the fix.

Bug reports that do not come with a PoC and code implementing a fix may qualify for a maximum of up to 30% of the potential reward outlined below, as determined by the Beanstalk Immunefi Committee (BIC). You can read more about the BIC here:

* [BIC Process](https://docs.bean.money/almanac/governance/beanstalk/bic-process)
* [BICM Dashboard](https://docs.bean.money/almanac/governance/beanstalk/bicm-dashboard)

All vulnerabilities noted in [any audit reports in the Beanstalk Audits repository](https://github.com/BeanstalkFarms/Beanstalk-Audits) (or otherwise known by the BIC, [BCM](https://docs.bean.money/almanac/governance/beanstalk/bcm-dashboard), or [Root DAO Multisig](https://docs.roottoken.org/governance/root-token/rdm-dashboard)) are not eligible for a reward.


# Links

* [**Website**](https://basin.exchange/)
* [**Basin Whitepaper**](https://basin.exchange/basin.pdf)
* [**Multi Flow Whitepaper**](https://basin.exchange/multi-flow-pump.pdf)
* [**Docs**](https://docs.basin.exchange/)
* [**Discord**](https://basin.exchange/discord)
* [**GitHub**](https://github.com/BeanstalkFarms#basin-1)
* [**Bug Bounty Program**](https://immunefi.com/bounty/beanstalk/)

### Documentation

* [Basin Whitepaper Repo](https://github.com/BeanstalkFarms/Basin-Whitepaper)
* [Multi Flow Pump Whitepaper Repo](https://github.com/BeanstalkFarms/Multi-Flow-Pump-Whitepaper)
* [Basin Docs Repo](https://github.com/BeanstalkFarms/Basin-Docs)
* [Basin Brand Assets](https://github.com/BeanstalkFarms/Beanstalk-Brand-Assets/blob/main/basin)

### Security

* [**Immunefi Bug Bounty Program**](https://immunefi.com/bounty/beanstalk)
* [**Basin Audits**](https://github.com/BeanstalkFarms/Beanstalk-Audits#ecosystem-audit-reports-on-arweave)
* [Bug Reports](https://community.bean.money/bug-reports)

### Social

* [**Basin Discord**](https://basin.exchange/discord)
* [**Basin Twitter**](https://twitter.com/basinexchange)
* [Basin Telegram Tracker](https://t.me/basintracker)
* [Beanstalk Farms Twitter](https://twitter.com/BeanstalkFarms)
* [Beanstalk Farms YouTube](https://www.youtube.com/@BeanstalkFarms)


