# Handover Document for LBP
This document focuses on how to interact with LBPManager, LBPManagerFactory, balancer's LBP and Vault.
## Creation Process
- The Creation process involves deploying and initializing the LBPManager.
- The dApp should send the `LBPManagerFactory.deployLBPManager()` transaction request to Gnosis, where the Multi-sig Owners can sign and execute transactions.
### Using `LBPManagerFactory.deployLBPManager()`
This method is responsible for deploying new LBPManager contracts and initializing its state variables.
#### Inputs
1. `_admin`: `Address` - The address of the admin of the LBPManager.
2. `_beneficiary`: `Address` - The address that receives the fee.
3. `_name`: `String` - Name of the LBP.
4. `_symbol`: `String` - Symbol of the LBP.
5. `_tokenList`: `Array<Address>` - Array of addresses, in lowercases, in order of:
1. Project token address.
2. Funding token address.
6. `_amounts`: `Array<uint256>` - Array of amounts of project and funding tokens to be added as liquidity. In order of:
1. Amounts of project token.
2. Amounts of funding Token.
7. `_startWeights`: `Array<uint256>` - Array of weights, in order of:
1. Start weight of project token.
2. Start weight of funding token.
8. `_startTimeEndTime`: `Array<uint256>` - Array of timestamps, in order of:
1. Start time.
2. End time.
9. `_endWeights`: `Array<uint256>` - Array of weights, in order of:
1. End weight of project token.
2. End weight of funding token.
10. `_fees`: `Array<uint256>` - Array of fees, in order of:
1. Percentage of fee paid for every swap in the LBP.
2. Percentage of fee paid to `_beneficiary` for providing the service of the LBP Manager.
11. `_metadata`: `bytes` - IPFS Hash of the LBP creation wizard information.
#### Outputs
It returns nothing.
#### Events
1. `LBPManagerDeployed(address indexed lbpManager, address indexed admin, bytes metadata)`
#### Example
1. Initialize `LBPManagerFactory` contract instance.
```javascript=
const lbpManagerFactoryInstance // LBPManagerFactory contract instance.
```
2. Set up parameters
```javascript=
const admin = '0xadd1234...'; // admin address
const beneficiary = '0xbee1234...'; // beneficiary address who should be credited with fee
const name = "Everlasting LBP"; // name of LBP
const symbol = "eLBP"; // symbol of LBP
const tokenList = ['']; // [project token address, funding token address]
const amounts = []; // [amount of project token, amount of funding token]
const startWeights = []; // [start weight of project token, start weight of funding token]
const startTimeEndTime; // [start timestamp, end timestamp]
const endWeights; // [end weight of project token, end weight of funding token]
const fees = [parseUnits('1','16'), 0]; //[swapFee percentage, fee that is collected for the service] - swapFee percentage initially should 1% or ( 0.01 x (10^18) ), fee that is collected for the service, initially should be 0
const metadata = "0x"; // IPFS Hash of the LBP creation wizard information.
```
3. Invoke method
```javascript=
await lbpManagerFactoryInstance.deployLBPManager(
admin,
beneficiary,
name,
symbol,
tokenList,
amounts,
startWeights,
startTimeEndTime,
endWeights,
fees,
metadata
);
/*
* Invoking the method `deployLBPManager()` should:
* 1. Create LBPManager
* 2. Initialize LBPManager
* 3. Transfer admin rights to the `admin` address
* 4. Emit event `LBPManagerDeployed`
```
### Sending transaction to Gnosis.
1. Import Gnosis file.
```javascript=
import {api} from './Gnosis';
```
3. Set up Gnosis API.
```javascript=
const safeAddress = 'Address of gnosis safe';
const network = 'mainnet'; // the network you want to interact with. Supports mainnet and rinkeby
const gnosis = api(safeAddress, network);
```
5. Start Populating Transaction Object.
```javascript=
const transaction = {};
// lbpManagerFactoryInstance - LBPManager Factory contract instance
// safe - Safe contract instance. Artifacts will be provided
// signer - Signer contract instance
transaction.to = lbpManagerFactoryInstance.address;
transaction.value = 0;
transaction.operation = 0;
// lbpManagerArguments - array of arguments to be passed on to LBPManagerFactory.deployLBPManager()
// eg. lbpManagerArguments = [ //parameters needed for call to deployLBPManager()
// ADMIN,
// BENEFICIARY,
// name,
// symbol,
// [project token address, funding token address],
// [amount of project tokens, amount of funding tokens],
// [start weight of project token, start weight of funding token],
// [start timestamp, end timestamp],
// [end weight of project token, end weight of funding token],
// [swapFeePercentage, fee]
// metaData
// ]
transaction.data = (await lbpManagerFactoryInstance.populateTransaction.deployLBPManager(...lbpManagerArguments)).data;
```
7. Get Transaction Estimate.
```javascript=
const estimate = await gnosis.getEstimate(transaction);
transaction.safeTxGas = estimate.data.safeTxGas;
```
9. Set Safe Address.
```javascript=
transaction.safe = safe.address;
```
11. Add Payment Related Details.
```javascript=
transaction.baseGas = 0;
transaction.gasPrice = 0;
transaction.gasToken = '0x0000000000000000000000000000000000000000';
transaction.refundReceiver = '0x0000000000000000000000000000000000000000';
```
13. Get Nonce.
```javascript=
transaction.nonce = await gnosis.getCurrentNonce();
```
15. Call(), send details to Signer contract to generate hash and sign the hash.
```javascript=
// It returns an array object.
const {hash, signature} = await signer.callStatic.generateSignature(
transaction.to,
transaction.value,
transaction.data,
transaction.operation,
transaction.safeTxGas,
transaction.baseGas,
transaction.gasPrice,
transaction.gasToken,
transaction.refundReceiver,
transaction.nonce
);
transaction.contractTransactionHash = hash;
transaction.signature = signature;
```
17. Add sender to the transaction object.
```javascript=
transaction.sender = signer.address;
```
19. Send the transaction object to Gnosis Safe Transaction service.
```javascript=
await (await signer.generateSignature(
transaction.to,
transaction.value,
transaction.data,
transaction.operation,
transaction.safeTxGas,
transaction.baseGas,
transaction.gasPrice,
transaction.gasToken,
transaction.refundReceiver,
transaction.nonce)).wait()
.then(
async () => await gnosis.sendTransaction(transaction)
);
```
### What's changed between Seed and LBP.
Changes in terms of creation process of a Seed and a LBPManager using Gnosis Safe.
The only difference is in the way `transaction` object is created.
In seed,
```javascript=
transaction.to = seed.address;
transaction.data = (await seedFactory.populateTransaction.deploySeed(...seedArguments)).data;
```
But with LBPManager, the `to` and `data` properties are changed, everything else looks same.
```javascript=
transaction.to = lbpManagerFactoryInstance.address;
transaction.data = (await LBPManagerFactoryInstance.populateTransaction.deployLBPManager(...lbpManagerArguments)).data;
```
## Initializing LBP
The initialisation process involves creating the LBP, updating the weights, deducting fees and funding the pool.
For the Admin to initialize the LBP, these two steps are required:
1. Admin transfers allowance of the project and funding tokens to the LBPManager via the function `approve()`
2. Admin calls the function `LBPManager.initializeLBP()`
### Flow of to create and initialize LBP

### Using `LBPManager.initializeLBP()`
This method is responsible for creating and funding the LBP.
#### Input
1. _sender: `Address` - Address from which the project and funding tokens will be transferred from.
#### Output
It returns nothing.
#### Events
1. FeeTransferred(address indexed beneficiary, address tokenAddress, uint256 amount).
- This event only gets emitted if fees are being charged for providing the service of the LBPManager.
#### Example
1. Create instance of LBPManager.
```javascript=
const lbpManagerInstance = await LBPManager.attach("LBPManager Address emitted in event LBPManagerDeployed"); // Thing inside quote is a placeholder
```
2. Set up parameters.
***Note:** To approve the correct amount of project tokens to the LBPManger, we have to calculate the project fee amount from the fee percentage first. This amount wil then be added to the project tokens be approved to the LBPManager. The contract provides the view method `projectTokenRequired()` for this purpose.*
```javascript=
const senderAddress = sender.address; // account which will be debited with required amount to add project and funding tokens as liquidity.
const projectTokenIndex = await lbpManagerInstance.projectTokenIndex();
const tokenList = await lbpManagerInstance.amounts();
// To get the correct project token amount.
const projectTokenAmount = await lbpManagerInstance.projectTokensRequired(); // this is a view method. It returns a BigNumber. The value is the required amount of project tokens that needs to be approved. ProjectTokenRequired returns (Amount of Project tokens that needs to be added as liquidity) + (Amount of Project tokens that needs to be collected as fee).
// To get the correct funding token amount
const fundingTokenIndex = (projectTokenIndex == 0) ? 1 : 0;
const fundingTokenAmount = await lbpManagerInstance.amounts[fundingTokenIndex];// funding token amount is the same as mentioned during LBP registration wizard.
```
3. Set allowance for the project token and funding token.
```javascript=
await tokenList[projectTokenIndex].approve(lbpManagerInstance.address, projectTokenAmount); // adding allowance for LBPManager for required amount of project tokens including fees, which is initially zero.
await tokenList[fundingTokenIndex].approve(lbpManagerInstance.address, fundingTokenAmount); // adding allowance for LBPManager for required amount of funding tokens.
```
4. Invoking `initializeLBP()`.
```javascript=
await lbpManagerInstance.initializeLBP(senderAddress);
/*
* Invoking the method `initializeLBP()` should:
* 1. Create the LBP.
* 2. Update the weights.
* 3. Deduct the fees if applicable.
* i. If fee is being charged, it will emit the event `feeTransferred()`
* 4. Add liquidity to the LBP.
*/
```
## Pausing the LBP
### Using LBPManager.setSwapEnabled()
This method is responsible for setting the swap functionality of the LBP to true or false.
#### Input
1. swapEnabled: `bool` - Boolean that sets the swapping with the LBP to true or false
#### Output
It returns nothing
#### Events
No Event
#### Example
1. Set up parameters
```javascript=
const swapEnable = true;
```
2. Invoke `setSwapEnabled()`
```javascript=
await lbpManagerInstance.setSwapEnabled(swapEnable);
```
## Removing Liquidity (Exit Pool)
Removing liquidity involves exiting the pool and sending the project and funding tokens from the pool to the `_receiver` address.
### Using `LBPManager.removeLiquidity()`
This method is responsible for exiting the pool.
#### Input
1. _receiver: `Address` - Address which will be credited with the amount of project and funding tokens that got removed as liquidity from the pool.
#### Output
It returns nothing.
#### Events
No events.
#### Example
1. Set up parameters
```javascript=
const receiverAddress = receiver.address; // account which will be credited with amount to add project and funding tokens due to removal of liquidity from LBP.
```
2. Invoke `removeLiquidity()`
```javascript=
await lbpManagerInstance.removeLiquidity(receiverAddress);
/*
* Invoking the method `removeLiquidity()` should:
* 1. Exit the pool.
* 2. Send liquidity to the `_receiver` address.
*/
```
## Swapping
For swapping, the dApp needs to interact with `vault` directly.
Before Swapping, vault instance needs to be created and pool ID needs to be know.
```javascript=
const vaultInstance = await vault.attach("address of vault"); // Balancer's vault.
const poolId = await lbpInstance.getPoolID(); // this returns a bytes32 pool id.
```
### Swap Types
- Single swap
### Single Swap
Here, a token is given in and token is given out from a particular pool.
#### Example
1. Set up parameters
```javascript=
const user; // Signer object of the connected user that wants to do swapping.
const SWAP_KIND_EXACT_AMOUNTS_IN = 0; // this specifies the type of swapping, 0 - exact amount in for amount out.
const amountIn = parseEther('0.01'); // amount of funding token that needs to be swapped in, this is the amount that will be transfered to vault in exchange for project token.
```
```javascript=
fundingToken.connect(user).approve(vaultInstance.address, amountIn.toString()); // approve vault with required amount of funding tokens that needs to be swapped in.
const singleSwap = {
poolId: await lbpInstance.getPoolId(), // pool id
kind: 0, // this specifies the type of swapping, 0 - exact amount in for amount out.
assetIn: fundingToken.address, // token address that will be given in to the vault
assetOut: projectToken.address, // token address that will be given out from the vault
amount: amountIn.toString(), // amount that needs to be swapped in
userData: '0x' // this is fixed, as we don't need extra user data for swapping
};
const funds = {
sender: user.address, // address of account which will be debited with the amount.
fromInternalBalance: false, // always false, as we agreed not to use internal balances
recipient: user.address.address, // address that receives the swapped out amount
toInternalBalance: false // always false, as we agreed not to use internal balance
};
await vaultInstance.connect(user).swap(singleSwap, funds, parseEther('0.001').toString(), Date.now()+1000);
```
## Update Metadata
Updating the metadata process involves storing the new metadata in the state.
### Using `LBPManager.updateMetadata()`
This method is responsible for updating the metadata.
#### Input
1. _metadata: `Bytes` - IPFS has of the LBP wizard contract.
#### Output
It returns nothing.
#### Events
1. `MetadataUpdated(bytes indexed metadata)`
#### Example
1. Set up parameters
```javascript=
const newMetadata = "0x"; // IPFS Hash of the updated LBP creation wizard information.
```
2. Invoke `updateMetadata()`
```javascript=
await lbpManagerInstance.updateMetadata(newMetadata);
/*
* Invoking the method `updateMetadata()` should:
* 1. Update the metadata state in the LBPManager.
*/
```
## Transfer Admin Rights LBPManager
Updating the admin rights process involves storing the new admin address in the state.
### Using `LBPManager.transferAdminRights()`
This method is responsible for transfering the admin rights to the LBPManager.
#### Input
1. _newAdmin: `Address` - Address of the new admin to the LBPManager.
#### Output
It returns nothing.
#### Events
1. `LBPManagerAdminChanged(address indexed oldAdmin, address indexed newAdmin)`
#### Example
1. Set up parameters
```javascript=
const newAdminAddress = newAdmin.address; // Address of the new admin to the LBPManager
```
2. Invoke `transferAdminRights()`
```javascript=
await lbpManagerInstance.transferAdminRights(newAdminAddress);
/*
* Invoking the method `transferAdminRights()` should:
* 1. Update the admin address state in the LBPManager.
*/
```
# Things that won't be used by Frontend
## Withdrawing Pool Tokens
Withdrawing the pool token process involves sending all of the LBPManagers pool tokens balance to the `_receiver` address.
***IMPORTANT**: This method is an advanced user method. It will not be exposed through the UI. Read contract method disclaimer for more information.*
### Using `LBPManager.withdrawPoolTokens()`
This method is responsible withdrawing pool tokens from the LBPManager.
#### Input
1. _receiver: `Address` - Address which will be credited with the pool tokens.
#### Output
It returns nothing.
#### Events
1. `PoolTokensWithdrawn(address indexed LbpAddress, uint256 amount)`
#### Example
1. Set up parameters
```javascript=
const receiverAddress = receiver.address; // Account which will be credited with the project and funding tokens due to removal of liquidity from LBP.
```
2. Invoke `withdrawPoolTokens()`
```javascript=
await lbpManagerInstance.withdrawPoolTokens(receiverAddress);
/*
* Invoking the method `withdrawPoolTokens()` should:
* 1. Send LBPManagers balance of pool tokens to `_receiver` address.
*/
```
## Transfer LBPManagerFactory Ownership
LBPManagerFactory is inherit from the Ownable contract. For the process of transferring the ownership of the contract, we use OpenZeppelin's `transferOwnership()` function. [Link to the contract](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol)
### Using `LBPManagerFactory.transferOwnership()`
OpenZeppelin's method which is responsible for transfering the ownership of the LBPManagerFactory.
#### Input
1. _newOwner: `Address` - Address of the new owner of the LBPManagerFactory.
#### Output
It returns nothing.
#### Events
1. `OwnershipTransferred(address indexed previousOwner, address indexed newOwner)`
#### Example
1. Set up parameters
```javascript=
const newOwnerAddress = newOwner.address; // Address of the new owner of the LBPManagerfactory
```
2. Invoke `transferOwnership()`
```javascript=
await lbpManagerFactoryInstance.transferOwnership(newOwnerAddress);
```
## Set LBPFactory Master Copy
Updating Balancer's LBPFactory address involves storing the new LBPFactory address in the state.
### Using `LBPManagerFactory.setLBPFactory()`
This method is responsible for updating the LBPFactory address.
#### Input
1. _lbpFactory: `Address` - Address of the new LBPFactory which is used for creating the LBPs.
#### Output
It returns nothing.
#### Events
1. `LBPFactoryChanged(address indexed oldLBPFactory, address indexed newLBPFactory)`
#### Example
1. Set up parameters
```javascript=
const newLBPFactory = LBPFactory.address; // Address of the new Balancer LBPFactory.
```
2. Invoke `setLBPFactory()`
```javascript=
await lbpManagerFactoryInstance.setLBPFactory(newLBPFactory);
/*
* Invoking the method `setLBPFactory()` should:
* 1. Update the LBPFactory address state in the LBPManager.
*/
```