DEV Community

Cover image for How equillar manage investment commissions
Nacho Colomina Torregrosa
Nacho Colomina Torregrosa

Posted on • Originally published at docs.equillar.com

How equillar manage investment commissions

How equillar manage investment commissions

When creating the equillar smart-contract, one of the most important decisions was how to structure commissions. Instead of applying a single fixed percentage, we have implemented a dynamic commission system that rewards larger investments with lower rates. This approach incentivizes significant capital contributions while maintaining a fair and accessible base rate for smaller investors.

The Philosophy: Decreasing Commissions

The central idea of our system is simple: the more you invest, the lower the commission percentage you pay. This approach has several benefits:

  • Accessibility: Small investors aren't penalized with disproportionate commissions
  • Incentive: Encourages larger investments by offering better conditions
  • Fairness: Balances operational costs with fair treatment for everyone

The Rate Denominator

To implement this dynamic system, we use a variable called the rate denominator. This is the key piece that makes commissions adjust automatically. Let's explore how it works

The calculate_rate_denominator function

Here's the actual contract code that calculates the rate denominator:

pub(self) const LOWER_AMOUNT_FOR_COMMISSION_REDUCTION: i128 = 100;
pub(self) const LOWER_DIVISOR: u32 = 10;
pub(self) const UPPER_DIVISOR: u32 = 60;
pub(self) const AMOUNT_PER_COMMISSION_REDUCTION: i128 = 400; 

pub fn calculate_rate_denominator(amount: &i128, decimals: u32) -> u32 {
    let scale_factor = 10_i128.pow(decimals);
    let token_amount = amount / scale_factor;

    if token_amount <= LOWER_AMOUNT_FOR_COMMISSION_REDUCTION {
        return LOWER_DIVISOR;
    }

    let a = (token_amount - LOWER_AMOUNT_FOR_COMMISSION_REDUCTION) 
            / AMOUNT_PER_COMMISSION_REDUCTION;

    if a > UPPER_DIVISOR as i128 {
        return UPPER_DIVISOR;
    }

    LOWER_DIVISOR + a as u32
}
Enter fullscreen mode Exit fullscreen mode

Let's break down how calculate_rate_denominator works step by step:

Decimal Handling (Lines 1-4)

let scale_factor = 10_i128.pow(decimals);
let token_amount = amount / scale_factor;
Enter fullscreen mode Exit fullscreen mode

First, the function converts the scaled amount (e.g., 3,600,000,000 for a token with 7 decimals such as USDC) to real token units (360). This is crucial because blockchain contracts receive amounts scaled by the token's decimals, but our logic needs to work with actual token quantities.

Base Tier Check (Lines 6-8)

if token_amount <= LOWER_AMOUNT_FOR_COMMISSION_REDUCTION {
    return LOWER_DIVISOR;
}
Enter fullscreen mode Exit fullscreen mode

If the investment is 100 tokens or less, we immediately return a rate denominator of 10. This is the "base" tier where all small investors are treated equally.

Tiered Calculation (Lines 10-11)

let a = (token_amount - LOWER_AMOUNT_FOR_COMMISSION_REDUCTION) / AMOUNT_PER_COMMISSION_REDUCTION;
Enter fullscreen mode Exit fullscreen mode

For investments above 100 tokens, we calculate how many 400-token tiers the investment spans:

  • First 100 tokens: Covered by base tier (rate denominator = 10)
  • Tokens 101-500: Still rate denominator = 10 (excess < 400, so 0 additional tiers)
  • Tokens 501-900: Rate denominator = 11 (excess ≥ 400, so +1 tier)
  • Tokens 901-1,300: Rate denominator = 12 (excess ≥ 800, so +2 tiers)
  • And so on...

This creates a tiered structure where every complete 400-token tier above the base reduces the commission percentage.

Maximum Cap (Lines 13-15)

if a > UPPER_DIVISOR as i128 {
    return UPPER_DIVISOR;
}
Enter fullscreen mode Exit fullscreen mode

We cap the rate denominator at 60 to prevent commissions from becoming unreasonably small. Even ultra-large investments (millions of tokens) will use a denominator of 60, which already provides significant commission reduction.

Final Calculation (Line 17)

LOWER_DIVISOR + a as u32
Enter fullscreen mode Exit fullscreen mode

The final denominator is the base (10) plus the number of 400-token tiers exceeded.

Why This Design?

The tier-based approach (every 400 tokens) creates a balanced system:

  • Gradual reduction: Commissions decrease smoothly, not in large jumps
  • Fair for all ranges: Small, medium, and large investors all benefit
  • Predictable: Easy to calculate and understand
  • Bounded: The cap prevents extreme edge cases

Real-World Examples

Investment Formula Calculation Rate Denominator
50 N/A (≤100) Base tier 10
100 N/A (=100) Base tier 10
300 10 + (300-100)/400 10 + 0 (200/400 = 0) 10
500 10 + (500-100)/400 10 + 1 (400/400 = 1) 11
900 10 + (900-100)/400 10 + 2 (800/400 = 2) 12
1700 10 + (1700-100)/400 10 + 4 (1600/400 = 4) 14
5000 10 + (5000-100)/400 10 + 12 (4900/400 = 12) 22
25000 10 + (25000-100)/400 10 + 62 → capped 60

As smart contracts do not work with floating-point numbers, division is always integer-based. This is why (for instance) the 300 amount case results in the base tier denominator.

Practical example

For a 1400 USDC investment:

  1. Unscale: 14000000000 / 10^7 = 1400 USDC
  2. Excess over base limit: 1400 - 100 = 1300 USDC
  3. 400-token tiers: 1300 / 400 = 3 (integer based division)
  4. Rate denominator: 10 + 3 = 13

Calculating the Final Commission

Once we have the rate denominator, the contract calculates the commission using this implementation:

let amount_to_commission = amount * (*i_rate as i128) / (rate_denominator as i128) / 100 / 100;
Enter fullscreen mode Exit fullscreen mode

The two divisions by 100 are necessary because:

  • First division: Converts the rate denominator to a percentage
  • Second division: Converts the interest rate to a percentage (e.g., 850 → 8.5%) since it comes scaled as 10^2 to allow interests with decimals like (8.5%).

Complete Example: Project with 8.5% Yield

Imagine a project offering 8.5% yield (represented as 850 in the contract). Maria decides to invest 360 USDC tokens.

Step 1: Calculate the Rate Denominator

// Input: 3,600,000,000 (360 USDC tokens with 7 decimals)
let scale_factor = 10_i128.pow(7); // 10,000,000
let token_amount = 3_600_000_000 / 10_000_000; // 360 tokens

// Since 360 > 100:
let a = (360 - 100) / 400; // (260) / 400 = 0
let rate_denominator = 10 + 0; // 10
Enter fullscreen mode Exit fullscreen mode

Step 2: Calculate the Commission

let i_rate = 850_u32; // 8.5%
let amount = 3_600_000_000_i128; // 360 scaled tokens

let amount_to_commission = (3_600_000_000 * 850) / 10 / 100 / 100;
// = 3_060_000_000_000 / 10 / 100 / 100
// = 306_000_000_000 / 100 / 100
// = 3_060_000_000 / 100
// = 30_600_000

// Unscaled: 30,600,000 / 10^7 = 3.06 tokens
Enter fullscreen mode Exit fullscreen mode

Result

  • Project yield: 8.5%
  • Commission on investment: 0.85% (10 times lower than the yield)
  • Absolute commission: 3.06 tokens
  • Tokens available for yield generation: 356.94 tokens (after 0.85% commission)

Commission Comparison by Invested Amount

Let's see how commission varies for a project with 8.5% yield across different amounts:

Investment Rate Denominator Commission (USDC) % Commission
50 10 0.43 0.85%
360 10 3.06 0.85%
1,000 12 7.08 0.71%
2,000 14 12.14 0.61%
5,000 22 19.32 0.39%
10,000 34 25.00 0.25%
50,000 60 (max) 70.83 0.14%

As you can see, the commission is inversely proportional to the amount invested, decreasing as the amount invested increases.

Conclusion

The dynamic commission system achieves a fair balance between sustainability and accessibility. By automatically adjusting rates based on investment size, we ensure that small investors have a fair entry point while rewarding larger commitments with better terms.

This approach, combined with transparent on-chain calculations and automatic token decimal handling, creates a commission structure that adapts to each investor's needs. The result is a system where everyone benefits: small investors keep more of their returns, large investors enjoy reduced costs, and the platform remains economically viable.

Top comments (0)