# Crypto Pool

## Contract Interface

### 1. Notations & Structs

#### 1.1. PoolResultType

```rust
pub type PoolResultType<BigUint> = ManagedVec<BigUint, EsdtTokenPayment<BigUint>>;
```

#### 1.2. AddLiquidityEvent

```rust
pub struct AddLiquidityEvent<M: ManagedTypeApi> {
    pub token_amounts: ManagedVec<M, BigUint<M>>,
    pub fee: BigUint<M>,
    pub lp_token_supply: BigUint<M>,
    pub lp_token_amount: BigUint<M>,
}
```

#### 1.3. RemoveLiquidityEvent

```rust
pub struct RemoveLiquidityEvent<M: ManagedTypeApi> {
    pub token_amounts: ManagedVec<M, BigUint<M>>,
    pub lp_token_supply: BigUint<M>,
    pub lp_token_amount: BigUint<M>,
}
```

#### 1.4. TokenExchangeEvent

```rust
pub struct TokenExchangeEvent<M: ManagedTypeApi> {
    pub sold_id: TokenIdentifier<M>,
    pub tokens_sold: BigUint<M>,
    pub bought_id: TokenIdentifier<M>,
    pub tokens_bought: BigUint<M>,
}
```

### 2. Write functions

#### 2.1. Add liquidity

```rust
#[payable("*")]
#[endpoint(addLiquidity)]
fn add_liquidity(&self, min_mint_amount: BigUint, opt_receiver: OptionalValue<ManagedAddress>) -> BigUint;
```

#### 2.2. Remove liquidity

```rust
#[payable("*")]
#[endpoint(removeLiquidity)]
fn remove_liquidity(&self, min_amounts: ManagedVec<BigUint>, opt_receiver: OptionalValue<ManagedAddress>) -> ManagedVec<BigUint>
```

#### 2.3. Exchange

```rust
#[payable("*")]
#[endpoint(exchange)]
fn exchange(&self, min_dy: BigUint) -> BigUint;
```

`dy`: the minimum amount of the output token

### 3. Read functions

#### 3.1. Estimate the return of exchanging

```rust
#[view(estimateAmountOut)]
fn get_dy(self, i: usize, j: usize, dx: BigUint) -> MultiValue2<BigUint, BigUint>
```

`dx`: input token amount

`i`: input token index

`j`: output token index

#### 3.2. Get pool state

```rust
#[derive(TopEncode, TopDecode, PartialEq, TypeAbi, Debug)]
pub enum State { Inactive, Active, ActiveNoSwaps }

#[view(getState)]
fn state(&self) -> State;
```

#### 3.3. Get LP token identifier

```rust
#[view(getLpTokenIdentifier)]
fn get_lp_token_identifier(&self) -> TokenIdentifier
```

#### 3.4. Get LP token supply

```rust
#[view(getLpTokenSupply)]
fn get_lp_token_supply(&self) -> BigUint
```

#### Get pool tokens

```rust
#[view(getTokens)]
fn get_tokens(&self) -> ManagedVec<TokenIdentifier>
```

#### 3.5. Get token balances

```rust
#[view(getBalances)]
fn get_balances(&self) -> ManagedVec<BigUint>
```

### 4. Events

#### 4.1. Token exchange

```rust
#[event("token_exchange")]
fn token_exchange_event(
    &self,
    #[indexed] buyer: ManagedAddress<Self::Api>,
    token_exchange_event: &TokenExchangeEvent<Self::Api>,
);
```

#### 4.2. Add liquidity

```rust
#[event("add_liquidity")]
fn add_liquidity_event(
    &self,
    #[indexed] provider: ManagedAddress<Self::Api>,
    add_liquidity_event: &AddLiquidityEvent<Self::Api>,
);
```

#### 4.3. Remove liquidity

```rust
#[event("remove_liquidity")]
fn remove_liquidity_event(
    &self,
    #[indexed] provider: ManagedAddress<Self::Api>,
    remove_liquidity_event: &RemoveLiquidityEvent<Self::Api>,
);
```
