> For the complete documentation index, see [llms.txt](https://docs.inverter.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.inverter.network/contracts/technical-reference/modules/funding-manager/bonding-curve/abstracts/bondingcurvebase_v1.sol.md).

# BondingCurveBase\_v1.sol

[Git Source](https://github.com/InverterNetwork/inverter-contracts/blob/649b450f02fc8b735c128ff0821467e71966c666/src/modules/fundingManager/bondingCurve/abstracts/BondingCurveBase_v1.sol)

**Inherits:** IBondingCurveBase\_v1, Module\_v1

**Author:** Inverter Network

Manages the issuance of token for collateral along a bonding curve in the Inverter Network, including fee handling and sell functionality control.

*Provides core functionalities for issuance operations, fee adjustments, and issuance calculations. Fee calculations utilize BPS for precision. Issuance-specific calculations should be implemented in derived contracts.*

### State Variables

#### BPS

*Base Points used for percentage calculation. This value represents 100%.*

```solidity
uint internal constant BPS = 10_000;
```

#### issuanceToken

*The token the curve will mint and burn from.*

```solidity
IERC20Issuance_v1 internal issuanceToken;
```

#### buyIsOpen

*Indicates whether the buy functionality is open or not. Enabled = true || disabled = false.*

```solidity
bool public buyIsOpen;
```

#### buyFee

*Buy fee expressed in base points, i.e. 0% = 0; 1% = 100; 10% = 1000.*

```solidity
uint public buyFee;
```

#### projectCollateralFeeCollected

Accumulated project trading fees collected from deposits made by users when engaging with the bonding curve-based funding manager. Collected in collateral.

```solidity
uint public projectCollateralFeeCollected;
```

#### \_\_gap

*Storage gap for future upgrades.*

```solidity
uint[50] private __gap;
```

### Functions

#### supportsInterface

*See {IERC165-supportsInterface}.*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(Module_v1)
    returns (bool);
```

#### buyingIsEnabled

*Modifier to guarantee the buying functionality is enabled.*

```solidity
modifier buyingIsEnabled();
```

#### validReceiver

*Modifier to guarantee token recipient is valid.*

```solidity
modifier validReceiver(address _receiver);
```

#### buyFor

Buy tokens on behalf of a specified receiver address.

*Redirects to the internal function `_buyOrder` by passing the receiver address and deposit amount.*

```solidity
function buyFor(address _receiver, uint _depositAmount, uint _minAmountOut)
    public
    virtual
    buyingIsEnabled
    validReceiver(_receiver);
```

**Parameters**

| Name             | Type      | Description                                                                     |
| ---------------- | --------- | ------------------------------------------------------------------------------- |
| `_receiver`      | `address` | The address that will receive the bought tokens.                                |
| `_depositAmount` | `uint256` | The amount of collateral token deposited.                                       |
| `_minAmountOut`  | `uint256` | The minimum acceptable amount the user expects to receive from the transaction. |

#### buy

Buy tokens for the sender's address.

*Redirects to the internal function `_buyOrder` by passing the sender's address and deposit amount.*

```solidity
function buy(uint _depositAmount, uint _minAmountOut) public virtual;
```

**Parameters**

| Name             | Type      | Description                                                                     |
| ---------------- | --------- | ------------------------------------------------------------------------------- |
| `_depositAmount` | `uint256` | The amount of collateral token depoisited.                                      |
| `_minAmountOut`  | `uint256` | The minimum acceptable amount the user expects to receive from the transaction. |

#### openBuy

Opens the buying functionality for the token.

*Only callable by the {Orchestrator\_v1} admin. Reverts if buying is already open.*

```solidity
function openBuy() external virtual onlyOrchestratorAdmin;
```

#### closeBuy

Closes the buying functionality for the token.

*Only callable by the {Orchestrator\_v1} admin. Reverts if buying is already closed.*

```solidity
function closeBuy() external virtual onlyOrchestratorAdmin;
```

#### setBuyFee

Sets the fee percentage for buying tokens, payed in collateral.

*Only callable by the {Orchestrator\_v1} admin. The fee cannot exceed 10000 basis points. Reverts if an invalid fee is provided.*

```solidity
function setBuyFee(uint _fee) external virtual onlyOrchestratorAdmin;
```

**Parameters**

| Name   | Type      | Description              |
| ------ | --------- | ------------------------ |
| `_fee` | `uint256` | The fee in basis points. |

#### calculatePurchaseReturn

Calculates the amount of tokens to be minted based on a given deposit amount.

*This function takes into account any applicable buy fees before computing the token amount to be minted. Revert when `_depositAmount` is zero.*

```solidity
function calculatePurchaseReturn(uint _depositAmount)
    public
    view
    virtual
    returns (uint mintAmount);
```

**Parameters**

| Name             | Type      | Description                                 |
| ---------------- | --------- | ------------------------------------------- |
| `_depositAmount` | `uint256` | The amount of tokens deposited by the user. |

**Returns**

| Name         | Type      | Description                                                              |
| ------------ | --------- | ------------------------------------------------------------------------ |
| `mintAmount` | `uint256` | The amount of new tokens that will be minted as a result of the deposit. |

#### withdrawProjectCollateralFee

Withdraw project collateral fee to the receiver address.

```solidity
function withdrawProjectCollateralFee(address _receiver, uint _amount)
    public
    virtual
    validReceiver(_receiver)
    onlyOrchestratorAdmin;
```

**Parameters**

| Name        | Type      | Description                            |
| ----------- | --------- | -------------------------------------- |
| `_receiver` | `address` | The address that will receive the fee. |
| `_amount`   | `uint256` | The amount of fee to withdraw.         |

#### getIssuanceToken

Returns the address of the issuance token.

```solidity
function getIssuanceToken() external view virtual returns (address);
```

#### getStaticPriceForBuying

Calculates and returns the static price for buying the issuance token.

```solidity
function getStaticPriceForBuying() external view virtual returns (uint);
```

**Returns**

| Name     | Type      | Description                                          |
| -------- | --------- | ---------------------------------------------------- |
| `<none>` | `uint256` | uint The static price for buying the issuance token. |

#### \_issueTokensFormulaWrapper

*Function used for wrapping the call to the external contract responsible for calculating the issuing amount. This function is an abstract function and must be implemented in the downstream contract.*

```solidity
function _issueTokensFormulaWrapper(uint _depositAmount)
    internal
    view
    virtual
    returns (uint);
```

**Parameters**

| Name             | Type      | Description                                       |
| ---------------- | --------- | ------------------------------------------------- |
| `_depositAmount` | `uint256` | The amount of collateral token that is deposited. |

**Returns**

| Name     | Type      | Description                                    |
| -------- | --------- | ---------------------------------------------- |
| `<none>` | `uint256` | uint Return the amount of tokens to be issued. |

#### \_buyOrder

*Internal function to handle the buying of tokens. This function performs the core logic for buying tokens. It transfers the collateral, deducts any applicable fees, and mints new tokens for the buyer.*

```solidity
function _buyOrder(address _receiver, uint _depositAmount, uint _minAmountOut)
    internal
    returns (uint totalIssuanceTokenMinted, uint collateralFeeAmount);
```

**Parameters**

| Name             | Type      | Description                                                                     |
| ---------------- | --------- | ------------------------------------------------------------------------------- |
| `_receiver`      | `address` | The address that will receive the bought tokens.                                |
| `_depositAmount` | `uint256` | The amount of collateral to deposit for buying tokens.                          |
| `_minAmountOut`  | `uint256` | The minimum acceptable amount the user expects to receive from the transaction. |

**Returns**

| Name                       | Type      | Description                                                          |
| -------------------------- | --------- | -------------------------------------------------------------------- |
| `totalIssuanceTokenMinted` | `uint256` | The total amount of issuance token minted during this function call. |
| `collateralFeeAmount`      | `uint256` | The amount of collateral token subtracted as fee.                    |

#### \_handleIssuanceTokensAfterBuy

Virtual function to handle issuance tokens after a successful buy.

```solidity
function _handleIssuanceTokensAfterBuy(
    address _receiver,
    uint _issuanceTokenAmount
) internal virtual;
```

**Parameters**

| Name                   | Type      | Description                                                |
| ---------------------- | --------- | ---------------------------------------------------------- |
| `_receiver`            | `address` | The address for which the issuance tokens will be handled. |
| `_issuanceTokenAmount` | `uint256` | The amount of issuance tokens to handle.                   |

#### \_handleCollateralTokensBeforeBuy

Virtual function to handle collateral tokens before a buy.

```solidity
function _handleCollateralTokensBeforeBuy(address _provider, uint _amount)
    internal
    virtual;
```

**Parameters**

| Name        | Type      | Description                                                |
| ----------- | --------- | ---------------------------------------------------------- |
| `_provider` | `address` | The address from which the collateral tokens will be sent. |
| `_amount`   | `uint256` | The amount of collateral tokens to handle.                 |

#### \_setBuyFee

*Sets the buy transaction fee, expressed in BPS.*

```solidity
function _setBuyFee(uint _fee) internal virtual;
```

**Parameters**

| Name   | Type      | Description                                     |
| ------ | --------- | ----------------------------------------------- |
| `_fee` | `uint256` | The fee percentage to set for buy transactions. |

#### \_getFunctionFeesAndTreasuryAddresses

*Returns the collateral and issuance fee percentage retrieved from the fee manager for a specific operation.*

```solidity
function _getFunctionFeesAndTreasuryAddresses(bytes4 _selector)
    internal
    view
    virtual
    returns (
        address collateralTreasury,
        address issuanceTreasury,
        uint collateralFeePercentage,
        uint issuanceFeePercentage
    );
```

**Returns**

| Name                      | Type      | Description                                                                                                 |
| ------------------------- | --------- | ----------------------------------------------------------------------------------------------------------- |
| `collateralTreasury`      | `address` | The address the protocol fee in collateral should be sent to.                                               |
| `issuanceTreasury`        | `address` | The address the protocol fee in issuance should be sent to.                                                 |
| `collateralFeePercentage` | `uint256` | The percentage fee to be collected from the collateral token being deposited or redeemed, expressed in BPS. |
| `issuanceFeePercentage`   | `uint256` | The percentage fee to be collected from the issuance token being deposited or minted, expressed in BPS.     |

#### \_calculateNetAndSplitFees

\*Calculates the proportion of the fees for the given amount and returns them plus the amount minus the fees. Reverts under the following two conditions:

* if (project fee + protocol fee) > BPS
* if protocol fee amount or project fee amounts == 0 given the fee percentage is not zero. This would indicate a rouding down to zero due to integer division.\*

```solidity
function _calculateNetAndSplitFees(
    uint _totalAmount,
    uint _protocolFee,
    uint _projectFee
)
    internal
    pure
    returns (uint netAmount, uint protocolFeeAmount, uint projectFeeAmount);
```

**Parameters**

| Name           | Type      | Description                                                                                   |
| -------------- | --------- | --------------------------------------------------------------------------------------------- |
| `_totalAmount` | `uint256` | The amount from which the fees will be taken.                                                 |
| `_protocolFee` | `uint256` | The protocol fee percentage in relation to the BPS that will be applied to the `totalAmount`. |
| `_projectFee`  | `uint256` | The project fee percentage in relation to the BPS that will be applied to the `totalAmount`.  |

**Returns**

| Name                | Type      | Description                                     |
| ------------------- | --------- | ----------------------------------------------- |
| `netAmount`         | `uint256` | The total amount minus the combined fee amount. |
| `protocolFeeAmount` | `uint256` | The fee amount of the protocol fee.             |
| `projectFeeAmount`  | `uint256` | The fee amount of the project fee.              |

#### \_processProtocolFeeViaTransfer

*Internal function to transfer protocol fees to the treasury.*

```solidity
function _processProtocolFeeViaTransfer(
    address _treasury,
    IERC20 _token,
    uint _feeAmount
) internal;
```

**Parameters**

| Name         | Type      | Description                           |
| ------------ | --------- | ------------------------------------- |
| `_treasury`  | `address` | The address of the protocol treasury. |
| `_token`     | `IERC20`  | The token to transfer the fees from.  |
| `_feeAmount` | `uint256` | The amount of fees to transfer.       |

#### \_processProtocolFeeViaMinting

```solidity
function _processProtocolFeeViaMinting(address _treasury, uint _feeAmount)
    internal;
```

#### \_setIssuanceToken

*Sets the issuance token for the FundingManager. This function updates the `issuanceToken` state variable and should be be overridden by the implementation contract if extra validation around the token characteristics is needed.*

```solidity
function _setIssuanceToken(address _issuanceToken) internal virtual;
```

**Parameters**

| Name             | Type      | Description                                          |
| ---------------- | --------- | ---------------------------------------------------- |
| `_issuanceToken` | `address` | The token which will be issued by the Bonding Curve. |

#### \_checkBuyIsEnabled

*Checks if the buy functionality is enabled.*

```solidity
function _checkBuyIsEnabled() internal view;
```

#### \_validateRecipient

*Validates the recipient address.*

```solidity
function _validateRecipient(address _receiver) internal view;
```

#### \_validateProjectFee

*Validates the project fee.*

```solidity
function _validateProjectFee(uint _projectFee) internal pure virtual;
```

#### \_projectFeeCollected

*Internal function to add project fee collected to the state variable*

```solidity
function _projectFeeCollected(uint _projectFeeAmount) internal virtual;
```

**Parameters**

| Name                | Type      | Description                 |
| ------------------- | --------- | --------------------------- |
| `_projectFeeAmount` | `uint256` | The amount of fee collected |

#### \_ensureNonZeroTradeParameters

*Ensures that the deposit amount and min amount out are not zero.*

```solidity
function _ensureNonZeroTradeParameters(uint _depositAmount, uint _minAmountOut)
    internal
    pure;
```

**Parameters**

| Name             | Type      | Description           |
| ---------------- | --------- | --------------------- |
| `_depositAmount` | `uint256` | Deposit amount.       |
| `_minAmountOut`  | `uint256` | Minimum amount out.\` |

#### \_mint

*Mints new tokens.*

```solidity
function _mint(address _to, uint _amount) internal virtual;
```

**Parameters**

| Name      | Type      | Description                   |
| --------- | --------- | ----------------------------- |
| `_to`     | `address` | The address of the recipient. |
| `_amount` | `uint256` | The amount of tokens to mint. |

#### \_burn

*Burns tokens.*

```solidity
function _burn(address _from, uint _amount) internal virtual;
```

**Parameters**

| Name      | Type      | Description                   |
| --------- | --------- | ----------------------------- |
| `_from`   | `address` | The address of the owner.     |
| `_amount` | `uint256` | The amount of tokens to burn. |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.inverter.network/contracts/technical-reference/modules/funding-manager/bonding-curve/abstracts/bondingcurvebase_v1.sol.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
