Building on Avalanche? Ava Labs can cover up to 75% of your audit, and we take 10% off our quote. Avalanche audits: up to 75% covered. See how

Work & reportsReport

Sweat EconomyBurn Model Changes Security Review

Guvenkaya reviewed the changes to the Sweat Economy burn model in the Sweat Claim smart contract.

Sweat Economy logo

Date of engagement: 22nd April 2024 - 26th April 2024

  • Timur GüvenkayaPrincipal advisor

Engagement Dashboard

Audit results

Guvenkaya conducted a security assessment of the Sweat Economy new burn model from 22nd April 2024 to 26th April 2024. During this engagement, a total of 3 findings were reported. All of the findings are low severity. All issues are fixed by the Sweat Foundation team.

Engagement record

Client
The Sweat Foundation Ltd
System
Sweat Claim contract on NEAR
Review period
22nd April 2024 - 26th April 2024
Reviewed baseline
8fcaa54079dfa69cc6f57ae8d2644de4001ed427
Paths in scope
4
Principal advisor
Timur Güvenkaya

Timeline

  1. Review start22nd April 2024
  2. Final report28th April 2024

Findings by severity

  • Critical 0
  • High 0
  • Medium 0
  • Low 3
  • Informational 0

Finding status at final report

3Raised
3Fixed

Remediation complexity

3Simple

Impact

3Moderate

Likelihood

3Rare

Advisory and Client

The advisory

Guvenkaya specializes in security for digital assets and financial infrastructure, from smart contracts and protocols to applications, infrastructure, custody and cryptography.

Our team, including the sitting Heads of Security at Gauntlet and Agora, brings experience from Kraken, OpenZeppelin, Binance, ZKsync, Nillion, Invicti and EY. Across the team: 200+ security reviews, $30B+ in volume secured, 13 published cryptography research papers, and credentials including OSCP, OSWE and CISM.

  • Every reviewer has a public bio and is named before you sign. We match expertise to your system, with a principal leading scoping and checking findings.

The client

The Sweat Foundation is an organization behind Sweat Economy, an innovative project at the intersection of fitness and crypto. It motivates users to stay active by converting their steps into SWEAT Token. This approach promotes health and fitness and works as an entry point to crypto for many users.

Scope and Review Boundaries

Review depths

Deep
Line-by-line review with explicit attack hypotheses, adversarial reasoning about state transitions, and reproduction attempts for each hypothesis that survived reading.
Supporting
The code was read for its effect on a reviewed flow. Behaviour outside that effect was not assessed.
Targeted
Entry points were exercised or triaged against the flow's security properties rather than read in full.

This is the code we read, and how closely. 4 paths are in scope.

PathReview depthScope note
src/migration/migration.rsDeepMigration
src/record/api.rsDeepRecord API
claim/api.rsDeepClaim API
model/src/account_record.rsDeepAccount Record

Out of scope

The audit will include, but is not limited to, reviewing the code for security vulnerabilities, coding practices, and architecture. The audit does not include a review of the dependencies. Only the changes to the burn model are in scope.

Assessment Framework

Guvenkaya rates findings by likelihood and impact so remediation can be prioritized by technical risk, business context, and the decision the engagement is meant to support.

Rating chain applied to every finding

  1. 01 Likelihood Likely, possible or rare
  2. 02 Impact Severe, moderate or negligible
  3. 03 Severity Derived from the matrix below
  4. 04 Remediation complexity Simple, moderate or difficult
  5. 05 Status Not fixed, fixed, acknowledged or scheduled

Impact

ImpactWhat it means here
SevereExploitation could result in critical loss or compromise, such as full system control, substantial financial loss, or severe reputational damage.
ModerateExploitation may lead to limited data loss, partial compromise, moderate financial impact, or noticeable degradation of services.
NegligibleExploitation has minimal impact, such as minor data exposure without significant consequences or slight inconvenience without substantial disruption.

Likelihood

LikelihoodWhat it means here
LikelyThe vulnerability is easily discoverable and not overly complex to exploit.
PossibleThe vulnerability presents some challenges either in discovery or in the complexity of the attack.
RareThe vulnerability is either very difficult to discover or complex to exploit, or both.

This matrix provides a nuanced view, taking into account both the ease of discovering a vulnerability and the complexity involved in exploiting it.

Attack Complexity \ Discovery EaseObviousConcealedHidden
ComplexPossibleRareRare
ModerateLikelyPossibleRare
StraightforwardLikelyPossiblePossible

Severity

SeverityWhat it means here
CriticalAssigned to vulnerabilities with severe impact and a likely likelihood of exploitation.
HighFor vulnerabilities with either severe impact but only a possible likelihood, or moderate impact with a likely likelihood.
MediumUsed for vulnerabilities with severe impact but a rare likelihood, moderate impact with a possible likelihood, or negligible impact with a likely likelihood.
LowFor vulnerabilities with moderate impact and rare likelihood, or negligible impact with a possible likelihood.
InformationalThe lowest severity rating, typically for vulnerabilities with negligible impact and a rare likelihood of exploitation.
Likelihood \ ImpactSevereModerateNegligible
LikelyCriticalHighMedium
PossibleHighMediumLow
RareMediumLowInformational

Remediation complexity

This measures how difficult it is to remediate a finding once it has been identified.

Remediation complexityWhat it means here
SimplePatches or fixes are readily available and easily implemented.
ModerateRequires some time and resources to remediate, but well within the capabilities of most organizations.
DifficultRemediation requires significant resources, specialized skills, or substantial changes to systems or architecture.

Finding status

This tracks the client's response to each finding and whether remediation has been completed, accepted, or scheduled.

StatusWhat it means here
Not FixedIndicates that the vulnerability has been identified but no remedial action has been taken yet. This status is crucial for newly discovered vulnerabilities or those awaiting prioritization.
FixedThis status is applied when the vulnerability has been successfully remediated. It implies that appropriate measures, such as patching, configuration changes, or architectural modifications, have been implemented to resolve the issue.
AcknowledgedThis status is used for vulnerabilities that have been recognized, but for various reasons (such as risk acceptance, cost, or other business decisions), have not been fixed. It indicates that the risk posed by the vulnerability is known and has been consciously accepted.
ScheduledThis status indicates that the vulnerability has been acknowledged and a plan is in place to fix it in the future. It signifies that while remediation hasn't yet occurred, the issue has been prioritized and is part of the planned development roadmap.

Findings Summary

3All findings
0 Critical
0 High
0 Medium
3 Low
0 Informational

Findings register

FindingImpactLikelihoodSeverityRemediation complexityStatus
GUV-1: Error Prone Burn Rate CalculationModerateRareLowSimpleFixed
GUV-2: Error Prone Getting Account APIModerateRareLowSimpleFixed
GUV-3: Lack of Prepaid Gas Checking Before Cross Contract CallsModerateRareLowSimpleFixed

Detailed Findings

GUV-1: Error Prone Burn Rate Calculation

Severity
Low
Impact
Moderate
Likelihood
Rare
Remediation Complexity
Simple
Status
Fixed
Fix commit
18a8f9d7c064f6fe89960eb7e07e1b0333faabff

Description

We observed that get_burn_rate uses floating point arithmetic in smart contracts, and then casts the result from a floating point number to a fixed point one. This approach is prone to errors as it could potentially cause truncation errors.

model:get_burn_rate:model/src/lib.rs
#[allow(    clippy::cast_possible_truncation,    clippy::cast_precision_loss,    clippy::cast_sign_loss)]pub fn get_burn_rate(balance: TokensAmount, burn_period: Duration) -> TokensAmount {    (balance as f64 / f64::from(burn_period)).ceil() as u128}

Recommendation

We propose using div_ceil which handles the division and the ceiling of the result, without utilizing floating point arithmetic.

Remediation

The Sweat Foundation team has fixed the issue by replacing the calculation with div_ceil in this commit: 18a8f9d7c064f6fe89960eb7e07e1b0333faabff

GUV-2: Error Prone Getting Account API

Severity
Low
Impact
Moderate
Likelihood
Rare
Remediation Complexity
Simple
Status
Fixed
Fix commits
417d42ea895aaf9193501b3b33ccc8b8a91e35b1 a0a9e4057a833b2d60c12ee7038a556dc9e8edde

Description

We noticed that the get_account_mut method not only gets the mutable reference to the account, but also inserts the account if it does not exist. This could lead to unexpected behavior and potential security vulnerabilities if this method is used without checking the implementation.

common:get_account_mut:contract/src/common/mod.rs
fn get_account_mut(&mut self, account_id: &AccountId) -> &mut AccountRecord {    if !self.contains_key(account_id) {        self.insert(account_id.clone(), AccountRecordVersioned::new(now_seconds()));    }     let AccountRecordVersioned::V1(account) = self.get_mut(account_id).expect("Account not found");    account}

Recommendation

We propose removing an account creation functionality from get_account_mut and creating a separate function called get_or_insert_account_mut which will use get_account_mut.

Remediation

The Sweat Foundation team has fixed the issue by implementing suggested fix in these commits: 417d42ea895aaf9193501b3b33ccc8b8a91e35b1 a0a9e4057a833b2d60c12ee7038a556dc9e8edde

GUV-3: Lack of Prepaid Gas Checking Before Cross Contract Calls

Severity
Low
Impact
Moderate
Likelihood
Rare
Remediation Complexity
Simple
Status
Fixed
Fix commit
06c59cdb1476d173de96a68ff82c00d4bf17e8bf

Description

We noticed that in both claim and burn methods, the contract does not check whether there is enough prepaid gas for cross-contract calls and callbacks. This could lead to the "Exceeded the prepaid gas" errors if not enough gas was attached

Recommendation

We propose checking whether env::prepaid_gas() is enough for the cross-contract call and callback before making a call.

Remediation

The Sweat Foundation team has fixed the issue by taking a difference between env::prepaid_gas and env::used_gas and asserting it in both claim and burn methods before cross-contract calls in this commit: 06c59cdb1476d173de96a68ff82c00d4bf17e8bf

The web version and the PDF (14 pages) are generated from the same source. The report as first delivered is kept in the public reports archive.

Tell us what you need to secure.

Describe your system, main concern, and deadline. We’ll reply with scoping questions and a proposed next step.

Discuss your scope