# nAlpha Vault

## Contract Addresses & Configuration

```jsx
// nALPHA vault addresses (same on both Plume and Eth chains)
const VAULT_ADDRESS = "0x593cCcA4c4bf58b7526a4C164cEEf4003C6388db"
const TELLER_ADDRESS = "0xc9F6a492Fb1D623690Dc065BBcEd6DfB4a324A35"
const ACCOUNTANT_ADDRESS = "0xe0CF451d6E373FF04e8eE3c50340F18AFa6421E1"

const INFRA = {
  predicateProxyAddress: "0x6104fe10ca937a086ba7AdbD0910A4733d380cB6",
  nativeFeeTokenAddress: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
  bridgeMessageGas: 100000,
}

const PLUME_MAINNET = {
  chainId: 98866,
  layerZeroEndpointId: 30370,
  atomicQueueAddress: "0x220dc6d4569c1f406d532f9633d5be5bc86e8264",
  depositToken: {
    address: "0xdddd73f5df1f0dc31373357beac77545dc5a6f3f",
    decimals: 6,
    symbol: "pUSD",
    defaultSlippagePercentage: 0.005,
  }
}

const ETH_MAINNET = {
  chainId: 1,
  layerZeroEndpointId: 30101,
  atomicQueueAddress: "0x220dc6d4569c1f406d532f9633d5be5bc86e8264",
  depositToken: {
    address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    decimals: 6,
    symbol: "USDC",
    defaultSlippagePercentage: 0.005,
  }
}

const VAULT_DECIMALS = 6
const PUSD_ADDRESS = PLUME_MAINNET.depositToken.address
const USDC_ADDRESS = ETH_MAINNET.depositToken.address
const PLUME_ATOMIC_QUEUE_ADDRESS = PLUME_MAINNET.atomicQueueAddress
const ETH_ATOMIC_QUEUE_ADDRESS = ETH_MAINNET.atomicQueueAddress
```

***

## Summary: 6 Distinct Paths

### Deposits (3 paths)

**USDC Ethereum -> nALPHA Plume (cross-chain)**:&#x20;

API compliance check, get exchange rate on Ethereum, compute minimumMint with slippage, calculate bridge fee, approve USDC on Ethereum, deposit and bridge to Plume.

pUSD Plume -> nALPHA Plume (same-chain): API compliance check, get exchange rate on Plume, compute minimumMint with slippage, approve pUSD on Plume, direct deposit on Plume.

USDC Ethereum -> nALPHA Ethereum (same-chain): API compliance check, get exchange rate on Ethereum, compute minimumMint with slippage, approve USDC on Ethereum, direct deposit on Ethereum.

### Redemptions (3 paths)

nALPHA Plume -> USDC Ethereum (cross-chain): preview Plume->Ethereum bridge fee, bridge shares to Ethereum, get exchange rate on Ethereum, compute atomicPrice with slippage, approve nALPHA on Ethereum, create withdrawal request for USDC on Ethereum, monitor Ethereum withdrawal status.

nALPHA Plume -> pUSD Plume (same-chain): get exchange rate on Plume, compute atomicPrice with slippage, approve nALPHA on Plume, create withdrawal request for pUSD on Plume, monitor Plume withdrawal status.

nALPHA Ethereum -> USDC Ethereum (same-chain): get exchange rate on Ethereum, compute atomicPrice with slippage, approve nALPHA on Ethereum, create withdrawal request for USDC on Ethereum, monitor Ethereum withdrawal status.

***

## DEPOSIT FLOWS

### Path 1: Ethereum -> Plume (Cross-Chain Deposit)

{% stepper %}
{% step %}

### 1. Compliance Check (isDepositAndBridge=true)

```http
GET https://api.nest.credit/v1/user/{userAddress}/compliance?chainId=1&isDepositAndBridge=true
```

Response: `{ data: { isCompliant: boolean, predicateMessage: {...} } }`
{% endstep %}

{% step %}

### 2. Exchange Rate Query

```solidity
// Call accountant on Ethereum
Accountant(ACCOUNTANT_ADDRESS).getRateInQuoteSafe(USDC_ADDRESS) -> rateInQuote
// Returns rate in USDC decimals (6), e.g., 1050000 = 1.05 USDC per nALPHA share
```

{% endstep %}

{% step %}

### 3. Calculate Minimum Mint

```jsx
// Step 3a: Calculate expected vault shares
const oneShare = 10n ** BigInt(VAULT_DECIMALS) // 10^6 = 1000000n
const exchangeAmount = (depositAmount * oneShare) / rateInQuote

// Step 3b: Apply slippage protection
const slippageFactor = 1 - ETH_MAINNET.depositToken.defaultSlippagePercentage // 0.995
const slippageBigInt = BigInt(Math.floor(slippageFactor * 1e6)) // 995000n
const minimumMint = (exchangeAmount * slippageBigInt) / 1_000_000n

// Example: 1000 USDC deposit with 1.05 rate and 0.5% slippage
// exchangeAmount = (1000000000n * 1000000n) / 1050000n = 952380952n
// minimumMint = (952380952n * 995000n) / 1000000n = 947619047n
```

{% endstep %}

{% step %}

### 4. Calculate Bridge Fee

```solidity
// Call teller to preview LayerZero bridge fee using expected share amount
const bridgeData = {
  chainSelector: PLUME_MAINNET.layerZeroEndpointId,
  destinationChainReceiver: userAddress,
  bridgeFeeToken: INFRA.nativeFeeTokenAddress,
  messageGas: INFRA.bridgeMessageGas,
  data: "0x"
}
Teller(TELLER_ADDRESS).previewFee(exchangeAmount, bridgeData) -> bridgeFee
```

{% endstep %}

{% step %}

### 5. Token Approval

```solidity
// Approve USDC to predicate proxy on Ethereum
USDC.approve(INFRA.predicateProxyAddress, depositAmount)
```

{% endstep %}

{% step %}

### 6. Cross-Chain Deposit

```solidity
// Execute deposit and bridge transaction on Ethereum
PredicateProxy(INFRA.predicateProxyAddress).depositAndBridge(
  USDC_ADDRESS,
  depositAmount,
  minimumMint,
  bridgeData,
  TELLER_ADDRESS,
  predicateMessage
) { value: bridgeFee }
```

Result: USDC deposited on Ethereum, nALPHA minted on Plume
{% endstep %}
{% endstepper %}

***

### Path 2: Plume -> Plume (Same-Chain Deposit)

{% stepper %}
{% step %}

### 1. Compliance Check

```http
GET https://api.nest.credit/v1/user/{userAddress}/compliance?chainId=98866&isDepositAndBridge=false
```

Response: `{ data: { isCompliant: boolean, predicateMessage: {...} } }`
{% endstep %}

{% step %}

### 2. Exchange Rate Query

```solidity
// Call accountant on Plume
Accountant(ACCOUNTANT_ADDRESS).getRateInQuoteSafe(PUSD_ADDRESS) -> rateInQuote
// Returns rate in pUSD decimals (6), e.g., 1050000 = 1.05 pUSD per nALPHA share
```

{% endstep %}

{% step %}

### 3. Calculate Minimum Mint

```jsx
// Step 3a: Calculate expected vault shares
const oneShare = 10n ** BigInt(VAULT_DECIMALS) // 10^6 = 1000000n
const exchangeAmount = (depositAmount * oneShare) / rateInQuote

// Step 3b: Apply slippage protection
const slippageFactor = 1 - PLUME_MAINNET.depositToken.defaultSlippagePercentage // 0.995
const slippageBigInt = BigInt(Math.floor(slippageFactor * 1e6)) // 995000n
const minimumMint = (exchangeAmount * slippageBigInt) / 1_000_000n
```

{% endstep %}

{% step %}

### 4. Token Approval

```solidity
// Approve pUSD to predicate proxy on Plume
pUSD.approve(INFRA.predicateProxyAddress, depositAmount)
```

{% endstep %}

{% step %}

### 5. Direct Deposit

```solidity
// Execute direct deposit on Plume
PredicateProxy(INFRA.predicateProxyAddress).deposit(
  PUSD_ADDRESS,
  depositAmount,
  minimumMint,
  userAddress,
  TELLER_ADDRESS,
  predicateMessage
)
```

Result: pUSD deposited on Plume, nALPHA minted on Plume
{% endstep %}
{% endstepper %}

***

### Path 3: Ethereum -> Ethereum (Same-Chain Deposit)

{% stepper %}
{% step %}

### 1. Compliance Check

```http
GET https://api.nest.credit/v1/user/{userAddress}/compliance?chainId=1&isDepositAndBridge=false
```

Response: `{ data: { isCompliant: boolean, predicateMessage: {...} } }`
{% endstep %}

{% step %}

### 2. Exchange Rate Query

```solidity
// Call accountant on Ethereum
Accountant(ACCOUNTANT_ADDRESS).getRateInQuoteSafe(USDC_ADDRESS) -> rateInQuote
// Returns rate in USDC decimals (6), e.g., 1050000 = 1.05 USDC per nALPHA share
```

{% endstep %}

{% step %}

### 3. Calculate Minimum Mint

```jsx
// Step 3a: Calculate expected vault shares
const oneShare = 10n ** BigInt(VAULT_DECIMALS) // 10^6 = 1000000n
const exchangeAmount = (depositAmount * oneShare) / rateInQuote

// Step 3b: Apply slippage protection
const slippageFactor = 1 - ETH_MAINNET.depositToken.defaultSlippagePercentage // 0.995
const slippageBigInt = BigInt(Math.floor(slippageFactor * 1e6)) // 995000n
const minimumMint = (exchangeAmount * slippageBigInt) / 1_000_000n
```

{% endstep %}

{% step %}

### 4. Token Approval

```solidity
// Approve USDC to predicate proxy on Ethereum
USDC.approve(INFRA.predicateProxyAddress, depositAmount)
```

{% endstep %}

{% step %}

### 5. Direct Deposit

```solidity
// Execute direct deposit on Ethereum
PredicateProxy(INFRA.predicateProxyAddress).deposit(
  USDC_ADDRESS,
  depositAmount,
  minimumMint,
  userAddress,
  TELLER_ADDRESS,
  predicateMessage
)
```

Result: USDC deposited on Ethereum, nALPHA minted on Ethereum
{% endstep %}
{% endstepper %}

***

## REDEMPTION FLOWS

### Path 1: Plume -> Ethereum (Cross-Chain Redemption)

{% stepper %}
{% step %}

### 1. Preview Bridge Fee

```solidity
// Quote the Plume -> Ethereum share bridge fee
const bridgeData = {
  chainSelector: ETH_MAINNET.layerZeroEndpointId,
  destinationChainReceiver: userAddress,
  bridgeFeeToken: INFRA.nativeFeeTokenAddress,
  messageGas: INFRA.bridgeMessageGas,
  data: "0x"
}
Teller(TELLER_ADDRESS).previewFee(shareAmount, bridgeData) -> bridgeFee
```

{% endstep %}

{% step %}

### 2. Bridge Shares to Ethereum

```solidity
// Bridge nALPHA shares from Plume to Ethereum
Teller(TELLER_ADDRESS).bridge(
  shareAmount,
  bridgeData
) { value: bridgeFee }
```

{% endstep %}

{% step %}

### 3. Exchange Rate Query for Withdrawal

```solidity
// After the bridge completes, get the current exchange rate on Ethereum
Accountant(ACCOUNTANT_ADDRESS).getRateInQuoteSafe(USDC_ADDRESS) -> rateInQuote
```

{% endstep %}

{% step %}

### 4. Calculate Atomic Price with Slippage

```jsx
// Calculate atomic price (exchange rate with slippage protection)
const slippageFactor = 1 - ETH_MAINNET.depositToken.defaultSlippagePercentage // 0.995
const slippageBigInt = BigInt(Math.floor(slippageFactor * 1e6)) // 995000n
const atomicPrice = (rateInQuote * slippageBigInt) / 1_000_000n

// Example: If rate is 1050000 (1.05 USDC per share) with 0.5% slippage
// atomicPrice = (1050000n * 995000n) / 1000000n = 1044750n
```

{% endstep %}

{% step %}

### 5. Vault Token Approval

```solidity
// Approve nALPHA shares to the Ethereum atomic queue
nALPHA.approve(ETH_ATOMIC_QUEUE_ADDRESS, shareAmount)
```

{% endstep %}

{% step %}

### 6. Create Cross-Chain Withdrawal Request

```solidity
// Create atomic request for USDC on Ethereum
AtomicQueue(ETH_ATOMIC_QUEUE_ADDRESS).updateAtomicRequest(
  VAULT_ADDRESS,
  USDC_ADDRESS,
  {
    deadline: timestamp + (10 * 24 * 60 * 60),
    atomicPrice: atomicPrice,
    offerAmount: shareAmount,
    inSolve: false
  }
)
```

{% endstep %}

{% step %}

### 7. Monitor Cross-Chain Withdrawal

```http
GET https://api.nest.credit/v1/vaults/nest-alpha-vault/pending-redemptions?chainId=1&user={userAddress}
```

Result: nALPHA bridged from Plume to Ethereum, then queued for USDC redemption on Ethereum
{% endstep %}
{% endstepper %}

***

### Path 2: Plume -> Plume (Same-Chain Redemption)

{% stepper %}
{% step %}

### 1. Exchange Rate Query for Withdrawal

```solidity
// Get current exchange rate on Plume
Accountant(ACCOUNTANT_ADDRESS).getRateInQuoteSafe(PUSD_ADDRESS) -> rateInQuote
```

{% endstep %}

{% step %}

### 2. Calculate Atomic Price with Slippage

```jsx
// Calculate atomic price (exchange rate with slippage protection)
const slippageFactor = 1 - PLUME_MAINNET.depositToken.defaultSlippagePercentage // 0.995
const slippageBigInt = BigInt(Math.floor(slippageFactor * 1e6)) // 995000n
const atomicPrice = (rateInQuote * slippageBigInt) / 1_000_000n
```

{% endstep %}

{% step %}

### 3. Vault Token Approval

```solidity
// Approve nALPHA shares to the Plume atomic queue
nALPHA.approve(PLUME_ATOMIC_QUEUE_ADDRESS, shareAmount)
```

{% endstep %}

{% step %}

### 4. Create Same-Chain Withdrawal Request

```solidity
// Create atomic request for pUSD on Plume
AtomicQueue(PLUME_ATOMIC_QUEUE_ADDRESS).updateAtomicRequest(
  VAULT_ADDRESS,
  PUSD_ADDRESS,
  {
    deadline: timestamp + (10 * 24 * 60 * 60),
    atomicPrice: atomicPrice,
    offerAmount: shareAmount,
    inSolve: false
  }
)
```

{% endstep %}

{% step %}

### 5. Monitor Same-Chain Withdrawal

```http
GET https://api.nest.credit/v1/vaults/nest-alpha-vault/pending-redemptions?chainId=98866&user={userAddress}
```

Result: nALPHA queued for pUSD redemption on Plume
{% endstep %}
{% endstepper %}

***

### Path 3: Ethereum -> Ethereum (Same-Chain Redemption)

{% stepper %}
{% step %}

### 1. Exchange Rate Query for Withdrawal

```solidity
// Get current exchange rate on Ethereum
Accountant(ACCOUNTANT_ADDRESS).getRateInQuoteSafe(USDC_ADDRESS) -> rateInQuote
```

{% endstep %}

{% step %}

### 2. Calculate Atomic Price with Slippage

```jsx
// Calculate atomic price (exchange rate with slippage protection)
const slippageFactor = 1 - ETH_MAINNET.depositToken.defaultSlippagePercentage // 0.995
const slippageBigInt = BigInt(Math.floor(slippageFactor * 1e6)) // 995000n
const atomicPrice = (rateInQuote * slippageBigInt) / 1_000_000n
```

{% endstep %}

{% step %}

### 3. Vault Token Approval

```solidity
// Approve nALPHA shares to the Ethereum atomic queue
nALPHA.approve(ETH_ATOMIC_QUEUE_ADDRESS, shareAmount)
```

{% endstep %}

{% step %}

### 4. Create Same-Chain Withdrawal Request

```solidity
// Create atomic request for USDC on Ethereum
AtomicQueue(ETH_ATOMIC_QUEUE_ADDRESS).updateAtomicRequest(
  VAULT_ADDRESS,
  USDC_ADDRESS,
  {
    deadline: timestamp + (10 * 24 * 60 * 60),
    atomicPrice: atomicPrice,
    offerAmount: shareAmount,
    inSolve: false
  }
)
```

{% endstep %}

{% step %}

### 5. Monitor Same-Chain Withdrawal

```http
GET https://api.nest.credit/v1/vaults/nest-alpha-vault/pending-redemptions?chainId=1&user={userAddress}
```

Result: nALPHA queued for USDC redemption on Ethereum
{% endstep %}
{% endstepper %}

***

## Key Calculation Formulas

**Minimum Mint (Deposits):**

```jsx
const oneShare = 10n ** BigInt(VAULT_DECIMALS)
const exchangeAmount = (depositAmount * oneShare) / rateInQuote
const slippageMultiplier = BigInt(Math.floor((1 - slippagePercentage) * 1e6))
const minimumMint = (exchangeAmount * slippageMultiplier) / 1_000_000n
```

**Atomic Price (Withdrawals):**

```jsx
const slippageMultiplier = BigInt(Math.floor((1 - slippagePercentage) * 1e6))
const atomicPrice = (rateInQuote * slippageMultiplier) / 1_000_000n
```

Both pUSD on Plume and USDC on Ethereum use 6-decimal quote units in this guide.
