The Last Markdown Editor, Ever

Preliminary Repository's https://cantina.xyz/code/8b94fd62-eea5-46fb-bed6-36ec5adf36af/README.mdhttps://github.com/cantina-forks/thala-modules/tree/mai

Summary

Formal verification of key modules within the Aave V3 codebase was conducted using an aggressive threat modeling approach with the prover. The process rigorously tested abort conditions, state consistency, authorization checks, and asset conservation to ensure secure and correct operation under all scenarios. This verification focused on mitigating potential threats and maintaining protocol integrity, ensuring the reliability of staking and reward mechanisms.

Modules include:

Spec Overview for aave_math::wad_ray_math.move

Functionality Details Verification Status
function wade_to_ray
Preconditions Input a must be non-negative (a >= 0). ✅
Preconditions Input a must not cause overflow when multiplied by WAD_RAY_RATIO (a <= U256_MAX / WAD_RAY_RATIO). ✅
Postconditions Result is a * WAD_RAY_RATIO. ✅
Postconditions Result is non-negative (result >= 0). ✅
Verification Consistency Overflow check: Ensure multiplication does not exceed u256 max value. ✅
Verification Consistency Non-negative input: Validate inout non-negative. ✅
Verification Consistency Non-negative input: Guarantees the result is non-negative. ✅
function wade_mul
Preconditions Inputs a and b must be non-negative (a >= 0, b >= 0). ✅
Preconditions The multiplication of a and b must not cause overflow (a <= (U256_MAX - HALF_WAD) / b). ✅
Postconditions Result is the product of a and b, rounded half up to the nearest Wad. ✅
Postconditions Result is non-negative (result >= 0). ✅
Verification Conditions Overflow Check: Ensures the product of a and b does not exceed u256 max value. ✅
Verification Conditions Non-Negative Inputs: Validates both inputs are non-negative. ✅
Verification Conditions Non-Negative Result: Guarantees the result is non-negative. ✅
function wade_mul
Preconditions Denominator b must be non-zero (b > 0). ✅
Preconditions Inputs a and b must be non-negative (a >= 0, b >= 0). ✅
Preconditions The division must not cause overflow (a <= (U256_MAX - b / 2) / WAD). ✅
Postconditions Result is the division of a by b, rounded half up to the nearest Wad. ✅
Postconditions Result is non-negative (result >= 0). ✅
Postconditions Result is non-negative (result >= 0). ✅
Verification conditions Division by Zero Check: Ensures denominator is not zero. ✅
Verification conditions Non-Negative Inputs: Validates both inputs are non-negative. ✅
Verification conditions Overflow Check: Ensures the division does not exceed u256 max value. ✅
Verification conditions Non-Negative Result: Guarantees the result is non-negative. ✅
function ray_div
Preconditions Denominator b must be non-zero (b > 0). ✅
Preconditions Inputs a and b must be non-negative (a >= 0, b >= 0). ✅
Preconditions The division must not cause overflow (a <= (U256_MAX - b / 2) / RAY). ✅
Postconditions Result is the division of a by b, rounded half up to the nearest Ray. ✅
Postconditions Result is non-negative (result >= 0). ✅
Verification conditions Division by Zero Check: Ensures denominator is not zero. ✅
Verification conditions Non-Negative Inputs: Validates both inputs are non-negative. ✅
Verification conditions Overflow Check: Ensures the division does not exceed u256 max value. ✅
Verification conditions Non-Negative Result: Guarantees the result is non-negative. ✅
function ray_mul
Preconditions Inputs a and b must be non-negative (a >= 0, b >= 0) ✅
Postconditions Result is the product of a and b, rounded half up to the nearest Ray. ✅
Postconditions Result is non-negative (result >= 0). ✅
Verification conditions Non-Negative Result: Guarantees the result is non-negative. ✅
Verification conditions Non-Negative Inputs: Validates both inputs are non-negative. ✅
function ray_to_wad
Processes stake actions, ensuring the resources and conditions are correct before accepting any stake. Verification is enabled to maintain consistency with the protocol rules. ✅
Preconditions nput a must be non-negative (a >= 0). ✅
Postconditions Result is the input a divided by WAD_RAY_RATIO, rounded half up to the nearest Wad. ✅
Postconditions Result is non-negative (result >= 0). ✅
Verification conditions Non-Negative Result: Guarantees the result is non-negative. ✅
Verification conditions Non-Negative Inputs: Validates both inputs are non-negative. ✅
  // Specification for wad_to_ray
    spec wad_to_ray {
        // Preconditions
        requires a >= 0; // Ensure non-negative input
        requires a <= U256_MAX / WAD_RAY_RATIO; // Ensure no overflow

        // Postconditions
        ensures result == a * WAD_RAY_RATIO;
        ensures result >= 0; // Result should be non-negative
    }

    // Attach the specification directly to the function
    spec wad_mul {
        // Preconditions
        requires a <= (U256_MAX - HALF_WAD) / b; // Ensure no overflow
        requires a >= 0; // Ensure non-negative input
        requires b >= 0; // Ensure non-negative input

        // Postconditions
        ensures result == if (a == 0 || b == 0) { 0 } else { (a * b + HALF_WAD) / WAD };
        ensures result >= 0; // Result should be non-negative
    }

      // Specification for wad_div
    spec wad_div {
        // Preconditions
        requires b > 0; // Denominator must be non-zero
        requires a <= (U256_MAX - b / 2) / WAD; // Ensure no overflow
        requires a >= 0; // Ensure non-negative input
        requires b >= 0; // Ensure non-negative input

        // Postconditions
        ensures result == if (a == 0) { 0 } else { (a * WAD + b / 2) / b };
        ensures result >= 0; // Result should be non-negative
    }

        // Specification for ray_div
    spec ray_div {
        // Preconditions
        requires b > 0; // Denominator must be non-zero
        requires a <= (U256_MAX - b / 2) / RAY; // Ensure no overflow
        requires a >= 0; // Ensure non-negative input
        requires b >= 0; // Ensure non-negative input

        // Postconditions
        ensures result == if (a == 0) { 0 } else { (a * RAY + b / 2) / b };
        ensures result >= 0; // Result should be non-negative
    }

        // Specification for ray_mul
    spec ray_mul {
        // Preconditions
        //this does not hold true here 
       // requires a <= (U256_MAX - HALF_RAY) / b; // Ensure no overflow
        requires a >= 0; // Ensure non-negative input
        requires b >= 0; // Ensure non-negative input

        // Postconditions
        ensures result == if (a == 0 || b == 0) { 0 } else { (a * b + HALF_RAY) / RAY };
        ensures result >= 0; // Result should be non-negative
    }

    // Specification for ray_to_wad
    spec ray_to_wad {
        // Preconditions
        requires a >= 0; // Ensure non-negative input

        // Postconditions
        ensures result == if (a % WAD_RAY_RATIO >= WAD_RAY_RATIO / 2) { a / WAD_RAY_RATIO + 1 } else { a / WAD_RAY_RATIO };
        ensures result >= 0; // Result should be non-negative
    }

}

Spec Overview for aave_math::math_utilis.move

Functionality Details Verification Status
function calculate_compounded_interest
Preconditions The interest rate must be non-negative. ✅
Preconditions The timestamps must be in chronological order (last update timestamp cannot be in the future)
Preconditions Input a must not cause overflow when multiplied by WAD_RAY_RATIO (a <= U256_MAX / WAD_RAY_RATIO). ✅
Postconditions The result is guaranteed to be at least equal to the base ray value(1.0 in ray format) ensures result >= wad_ray_math::ray(); ✅
Postconditions When no time has passed, the result equals exactly the base ray (no interest) ensures exp == 0 ==> result == wad_ray_math::ray(); ✅
Postconditions When no time has passed, the result equals exactly the base ray (no interest) ensures rate == 0 ==> result == wad_ray_math::ray() ✅
Postconditions When the interest rate is zero, the result equals exactly the base ray (no interest) ✅
Postconditions When time has passed and the rate is significant, interest will accrue (result > ray) ✅
Verification Consistency For special case of exactly 1 time unit passing: Either the result is exactly as calculated by the formula or for very small rates that would round to zero, a minimum interest of 1 is applied. ✅
function pow
Preconditions The base must be non-negative. ✅
Preconditions The exponent must be non-negative. ✅
Verification Conditions base == 0 && exponent > 0 ==> result == 0 should be true mathematically (0 raised to any positive power should be 0) ❌Acknowledged (Ideal fail)
Verification conditions base > 0 ==> result > 0 should also be true mathematically (any positive number raised to any power should be positive) ❌Acknowledged (Ideal fail)
function calculate_linear_interest
Preconditions requires rate >= 0. Ensures non-negative interest rate ✅
Preconditions equires last_update_timestamp <= timestamp::now_seconds() . Validates timestamp ordering. ✅
Postconditions ensures result >= wad_ray_math::ray()
Guarantees minimum interest result ✅
Postconditions ensures last_update_timestamp == timestamp::now_seconds() ==> result == wad_ray_math::ray(). Validates no interest accrual when no time has pass ✅
Postconditions ensures rate == 0 ==> result == wad_ray_math::ray()
Validates zero rate case ✅
Verification conditions ensures rate > 0 && last_update_timestamp < timestamp::now_seconds() ==> result …
Verifies correct interest calculation formula ✅
function percent_mul
Preconditions The value input must be non-negative. ✅
Preconditions The percentage input must be non-negative. ✅
Postconditions The result is guaranteed to be non-negative. ✅
Postconditions If either value or percentage is zero, the result must be zero. ✅
function percent_div
Preconditions Prevents division by zero by requiring percentage > 0. ✅
Preconditions Checks for overflow: value > (U256_MAX - HALF_PERCENTAGE_FACTOR) / PERCENTAGE_FACTOR. ❌ Fixed https://cantina.xyz/code/b6dada12-d99d-4710-b1d3-e8a69b9af616/findings?created_by=movejay&finding=82
Postconditions Guarantees non-negative output: result >= 0. ✅
Postconditions Validates zero input case: value == 0 ==> result == 0.
Postconditions Verifies correct calculation with proper rounding: result == (value * PERCENTAGE_FACTOR + percentage / 2) / percentage. ✅
Postconditions Ensures upper bound of result: result <= (value * PERCENTAGE_FACTOR) / percentage + 1. ✅