Skip to main content

QualityAssessment

QualityAssessment.sol is the on-chain oracle contract that records quality scores for RWA certificates. It supports two modes: a legacy 4-dimension model and a configurable N-dimension profile model. The profile model is used in production; the legacy model remains for backwards compatibility.

Source: contracts/oracle/QualityAssessment.sol.


Roles

Rolekeccak256 constantWho holds itWhat it allows
ADMIN_ROLEkeccak256("ADMIN_ROLE")Oracle adminConfigure profiles, rating bands, set methodology scores
ORACLE_ROLEkeccak256("ORACLE_ROLE")Oracle service accountassessQuality, assessQualityFlexible
ROLE_MANAGERkeccak256("ROLE_MANAGER")AdminGrant/revoke ORACLE_ROLE

Assessment Modes

Legacy 4-Dimension Model (assessQuality)

Four fixed dimensions, each capped at 25 points (total max = 100):

DimensionMax scoreDescription
vintageScore25Age of the credit — newer is higher
methodologyScore25Verification standard used (VCS = 20, GS = 23, etc.)
additionalityScore25Whether the benefit would have occurred without the project
coBenefitsScore25SDGs, social impact, co-benefits
function assessQuality(
string memory _certificateSerial,
AssetType _assetType,
uint8 _vintageScore,
uint8 _methodologyScore,
uint8 _additionalityScore,
uint8 _coBenefitsScore
) external onlyRole(ORACLE_ROLE)

Result stored in qualityMetrics[serial]. Emits QualityAssessed and QualityMetricsUpdated.


Configurable N-Dimension Model (assessQualityFlexible)

Dimensions are configured per asset type by ADMIN_ROLE using configureQualityProfile. Scores are submitted per-dimension and normalized to 0–100.

function assessQualityFlexible(
string calldata _certificateSerial,
uint8 _assetType,
uint8[] calldata _scores
) external onlyRole(ORACLE_ROLE)

Requirements:

  • A quality profile must be configured for _assetType (profileConfigured[_assetType] == true).
  • _scores.length must equal the configured dimension count.
  • Each score must not exceed its dimension's maxScore.

Normalization: normalizedScore = (rawTotal × 100) / maxPossible.

The rating is resolved from the configured rating bands. Result stored in flexibleAssessments[serial]. Emits FlexibleQualityAssessed.


Quality Profiles

A quality profile defines the dimensions used for flexible assessment:

struct QualityDimension {
string name; // e.g. "Technical Quality", "Additionality"
uint8 maxScore; // Maximum points for this dimension
}

Configure a Profile

function configureQualityProfile(
uint8 _assetType,
string[] calldata _names,
uint8[] calldata _maxScores
) external onlyRole(ADMIN_ROLE)

Replaces any existing profile. The maxScores array must sum to the total possible score before normalization. The oracle normalizes the raw total to 0–100.

Production profiles for carbon credits use 6 dimensions with max scores [25, 20, 20, 15, 12, 8] (sum = 100), so normalization is a no-op in practice.

Read a Profile

function getQualityProfile(uint8 _assetType)
external view returns (QualityDimension[] memory)

Rating Bands

Rating bands map normalized score ranges to letter grades:

struct RatingBand {
string label; // e.g. "AAA", "AA", "A", "BBB"
uint8 minScore; // Minimum score for this band (inclusive)
}

Bands must be configured in descending order of minScore (highest rating first). The oracle walks the array and returns the first band where score >= minScore.

Configure Bands

function configureRatingBands(
uint8 _assetType,
string[] calldata _labels,
uint8[] calldata _minScores
) external onlyRole(ADMIN_ROLE)

Default bands (carbon credits)

BandMin score
AAA90
AA80
A70
BBB60
Not Eligible0

Read Bands

function getRatingBands(uint8 _assetType)
external view returns (RatingBand[] memory)

function getRating(uint8 _assetType, uint8 _score)
external view returns (string memory)

Vintage Score Helper

function calculateVintageScore(uint256 _vintage) public view returns (uint8)
Credit ageScore
0–2 years25
3–5 years20
6–10 years15
11–15 years10
> 15 years5

The oracle uses this to auto-derive the vintage dimension score rather than asking the registry to provide it.


Default Methodology Scores (Carbon)

Set during initialize. Overridable with setMethodologyScore (ADMIN_ROLE).

MethodologyScore (0–25)
Gold Standard (GS)23
Verified Carbon Standard (VCS)20
Climate Action Reserve (CAR)18
American Carbon Registry (ACR)18
Clean Development Mechanism (CDM)15

Minimum Quality Threshold

function meetsQualityThreshold(string memory _certificateSerial)
external view returns (bool)

Returns true when the certificate's score meets the per-asset-type minimum. If no minimum is configured for an asset type, DEFAULT_MIN_QUALITY_SCORE = 60 applies.

Default minimums set in initialize:

Asset typeMin score
Carbon, Plastic60
Nitrogen, Phosphorus, Water55
Agricultural Land50

Key View Functions

FunctionReturns
getQualityMetrics(serial)Legacy QualityMetrics struct
getFlexibleAssessment(serial)FlexibleAssessment struct (flexible mode)
getDimensionScores(serial, assetType)Per-dimension scores as uint8[]
getQualityScore(serial)totalScore from legacy metrics
getRating(assetType, score)Rating band label for a given score
getQualityProfile(assetType)Configured dimension array
getRatingBands(assetType)Configured band array
meetsQualityThreshold(serial)Whether score ≥ minimum for its asset type
calculateVintageScore(vintage)Legacy vintage helper

Events

EventWhen emitted
QualityAssessed(serial, assetType, totalScore, assessor)assessQuality
QualityMetricsUpdated(serial, assetType, v, m, a, c)assessQuality
FlexibleQualityAssessed(serial, assetType, totalScore, rating, assessor)assessQualityFlexible
QualityProfileConfigured(assetType, dimensionCount)configureQualityProfile
RatingBandsConfigured(assetType, bandCount)configureRatingBands
MethodologyScoreSet(assetType, methodology, score)setMethodologyScore
MinQualityScoreSet(assetType, minScore)setMinQualityScore

Custom Errors

ErrorCondition
ProfileNotConfigured(assetType)assessQualityFlexible called before profile is configured
DimensionCountMismatch(expected, provided)_scores.length does not match configured dimensions
ScoreExceedsMax(dimIndex, score, maxScore)A dimension score exceeds its maxScore
EmptyDimensionsconfigureQualityProfile called with zero dimensions
EmptyBandsconfigureRatingBands called with zero bands
BandsNotDescendingBands not in descending minScore order
NoBandsConfigured(assetType)Rating lookup on unconfigured asset type

UUPS Upgrade

_authorizeUpgrade requires ADMIN_ROLE. A 30-slot storage gap (uint256[30] private __gap) is reserved for future upgrades.