Skip to content

RAAC Token

Overview

$RAAC is RAAC's ecosystem token, managing and coordinating its various components including RWf(x), RAACLend index, as well as $RAAC distributions.


Architecture

RAAC Token Architecture

Contracts

The following contracts work together to implement the RAAC Token system:

Contract Description
RAACToken.sol The ERC20 RAAC token contract
RAACMinter.sol Manages the 41.92% ecosystem emissions, controlling minting of RAAC tokens to gauges
EmissionSchedule.sol Library that determines how much RAAC should be minted over time based on the predefined weekly ecosystem distribution schedule

Tokenomics

Total Supply: 21,000,000

RAAC Token Allocation

Allocations

Allocation Percentage Description
Ecosystem 41.92% Distributed via emissions to gauges, controlled by RAAC Minter
Treasury & Other 58.08% Team, treasury, partnerships, and vesting allocations

41.92% of supply is allocated for the ecosystem. Ecosystem token distributions follow a fixed schedule and their destination is decided by $veRAAC holders.

Ecosystem Token Distribution

41.92% of total $RAAC supply is earmarked for the ecosystem.

Ecosystem distributions are done in $leRAAC. $leRAAC is RAAC's fork of Clever's clevCVX, a wrapper for $veRAAC. $leRAAC is described in more detail in the $leRAAC section.

Distribution Mechanism

In order to distribute $leRAAC instead of $RAAC while still minting based on the emission schedule, the following process occurs:

  1. RAAC Token is minted to the gauges according to the emission schedule
  2. When a user claims their rewards from the RAAC Gauge:
    • The claimed $RAAC is deposited into the leRAAC Liquid Locker
    • $leRAAC is minted at 50% LTV on behalf of the user
  3. User receives $leRAAC rather than raw $RAAC

This mechanism ensures emissions follow the predetermined schedule while distributing the locked token variant to ecosystem participants.

Auditor Note

The leRAAC contracts are not in scope for this audit.

Emission Schedule

The amount of $RAAC emitted per week is set on a decaying schedule:

  • For the first 104 weeks, emissions will remain constant
  • After 104 weeks, emissions will be reduced by 5% every 13 weeks
  • This results in a reduction of approximately 18.55% per year
  • Emissions will run for a total of 780 weeks

RAAC Token Ecosystem Emissions

Auditor Note

EmissionSchedule is the library that implements this algorithm. The RAAC Minter calculates the minting amount using the tick method and mints the tokens.

Cumulative Distribution

RAAC Token Cumulative Distribution

Ecosystem distributions are frontloaded to kickstart protocol and treasury growth while providing a long-tail of emissions, with the intention of giving RAAC time to become self-sustaining.

Timeframe Cumulative Distribution
After Year 1 15.58% of ecosystem tokens
After Year 2 31.15% of ecosystem tokens
After Year 3 44.88% of ecosystem tokens

$veRAAC holders decide where ecosystem distributions flow. $RAAC emissions are allocated to gauges based on the percentage of weekly votes gauges receive.

Circulating Supply

The actual circulating supply depends on multiple factors, including how $leRAAC holders use the mechanics, $veRAAC yield and $RAAC price, and therefore cannot be determined upfront.


Key Features

Minting

  • Initial supply minted to Safe Wallet at deployment
  • Ongoing emissions controlled exclusively by RAAC Minter
  • Emission rate follows a predetermined schedule

Burning

Important: RAAC Token Can Be Burnt

The RAAC Token supports burning functionality. Tokens can be permanently destroyed, reducing the total supply. This is an irreversible action.

Burnt Tokens Are Not Re-minted

The RAAC Minter only mints tokens according to the predetermined emission schedule. Burnt tokens are never re-minted. When tokens are burned, they are permanently removed from circulation, and the minter does not compensate for the reduced supply. This means burning effectively reduces the maximum possible circulating supply of RAAC tokens.


Functions

RAACToken.sol

setMinter

setMinter(address _minter) external onlyOwner

Summary Sets the minter address that is authorized to mint new RAAC tokens.

Deployment Configuration

This function is called at time of deployment to configure the RAACMinter contract as the authorized minter.

Guarded Method - Callable only by the contract owner.

Parameters

Name Type Description
_minter address Address to set as the authorized minter

Reverts

  • If caller is not the owner

mint

mint(address to, uint256 amount) external onlyMinter

Summary Mints new RAAC tokens to the specified address.

RAACMinter Integration

This function is exclusively used by the RAACMinter contract to mint tokens according to the emission schedule.

Guarded Method - Callable only by the authorized minter address.

Parameters

Name Type Description
to address Recipient address for the minted tokens
amount uint256 Amount of RAAC tokens to mint

Reverts

  • If caller is not the authorized minter

burn

burn(uint256 amount) external

Summary Burns RAAC tokens from the caller's balance, permanently reducing the total supply.

Irreversible Action

Burnt tokens are permanently destroyed and are never re-minted by the emission schedule.

Parameters

Name Type Description
amount uint256 Amount of RAAC tokens to burn

Reverts

  • If caller has insufficient balance
Example (TypeScript / ethers)
const tx = await raacToken.burn(parseUnits("100", 18));
await tx.wait();

RAACMinter.sol

tick

tick() public nonReentrant whenNotPaused

Summary Triggers the minting process and updates the emission rate. Mints tokens according to the emission schedule and distributes them to registered distribution pools.

Integration and Automation

This method is typically integrated into high-activity contracts such as lending and borrowing pools to ensure regular emission updates. While not currently integrated into the RAAC lending ecosystem, it will be added to governance contracts. In the meantime, Chainlink Automation can be used to call this function periodically.

Guarded Method - Protected by nonReentrant modifier. - Can be paused via governance.

Parameters - None

Reverts

  • If contract is paused
  • If no distribution pools are configured
Example (TypeScript / ethers)
const tx = await raacMinter.tick();
await tx.wait();

activate

activate() external onlyRole(UPDATER_ROLE)

Summary Activates the minting process, enabling the emission schedule to begin.

Deployment Configuration

This function is called at time of deployment to activate the minter and start the emission schedule.

Guarded Method - Callable only by accounts with the UPDATER_ROLE.

Parameters - None

Reverts

  • If caller does not have the UPDATER_ROLE
  • If minter is already activated
Example (TypeScript / ethers)
const tx = await raacMinter.activate();
await tx.wait();

calculateScheduledMintableAmount

calculateScheduledMintableAmount(uint256 startPeriod, uint256 endPeriod) public view returns (uint256)

Summary Calculates the amount of RAAC tokens that can be minted between startPeriod and endPeriod based on the emission schedule.

Parameters

Name Type Description
startPeriod uint256 Starting period for the calculation
endPeriod uint256 Ending period for the calculation

Returns

Type Description
uint256 Amount of RAAC tokens mintable in the given range
Example (TypeScript / ethers)
const mintableAmount = await raacMinter.calculateScheduledMintableAmount(0, 52);
console.log("Mintable in first year:", mintableAmount.toString());

addDistributionPool

addDistributionPool(address pool, uint256 weight) external onlyRole(UPDATER_ROLE)

Summary Adds a distribution pool to receive minted RAAC tokens based on the specified weight.

Expected Configuration

As of now, the GaugeRewardDistributor (upcoming) is expected to be the only pool with 100% weight allocation.

Guarded Method - Callable only by accounts with the UPDATER_ROLE.

Parameters

Name Type Description
pool address Address of the distribution pool to add
weight uint256 Weight allocation for the pool (basis points)

Reverts

  • If caller does not have the UPDATER_ROLE
  • If pool address is zero
  • If pool already exists
Example (TypeScript / ethers)
const tx = await raacMinter.addDistributionPool(gaugeRewardDistributor, 10000); // 100%
await tx.wait();

removeDistributionPool

removeDistributionPool(address pool, bool excludeTick) external onlyRole(UPDATER_ROLE)

Summary Removes a distribution pool from the contract, stopping it from receiving future emissions.

Guarded Method - Callable only by accounts with the UPDATER_ROLE.

Parameters

Name Type Description
pool address Address of the distribution pool to remove
excludeTick bool If true, skips calling tick() before removal

Reverts

  • If caller does not have the UPDATER_ROLE
  • If pool does not exist
Example (TypeScript / ethers)
const tx = await raacMinter.removeDistributionPool(oldPoolAddress, false);
await tx.wait();

manageDistributionPool

manageDistributionPool(address pool, uint256 weight) external onlyRole(UPDATER_ROLE)

Summary Manages an existing distribution pool by updating its weight allocation.

Guarded Method - Callable only by accounts with the UPDATER_ROLE.

Parameters

Name Type Description
pool address Address of the distribution pool to manage
weight uint256 New weight allocation for the pool

Reverts

  • If caller does not have the UPDATER_ROLE
  • If pool does not exist
Example (TypeScript / ethers)
const tx = await raacMinter.manageDistributionPool(poolAddress, 5000); // 50%
await tx.wait();