Date of engagement: 7th May 2025 - 12th May 2025
-
Timur GüvenkayaPrincipal advisor
Engagement Dashboard
Audit results
Guvenkaya conducted a security assessment of the Sweat migration and refactor changes inside the Sweat Jar smart contract. During this engagement, 2 findings were reported. One is Medium severity and the other is Informational severity. The Sweat Foundation team has fixed both issues.
Engagement record
- Client
- The Sweat Foundation Ltd
- System
- Sweat Jar contract on NEAR
- Review period
- 7th May 2025 - 12th May 2025
- Paths in scope
- 6
- Principal advisor
- Timur Güvenkaya
Timeline
- Review start7th May 2025
- Draft report12th May 2025
- Final report12th May 2025
Findings by severity
Finding status at final report
Remediation complexity
Impact
Likelihood
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. 6 paths are in scope. Each path links to the file at the reviewed commit.
| Path | Review depth | Scope note |
|---|---|---|
contract/ | Deep | Sweat Jar Contract |
contract/ | Deep | Sweat Jar Contract |
model/ | Deep | Sweat Jar Contract |
contract/ | Deep | Sweat Jar Contract |
contract/ | Deep | Sweat Jar Contract |
contract/ | Deep | Sweat Jar Contract |
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.
Scope only includes:
- New Migration Functionality: Migration code in new contract and old contract
- Restaking changes: Addition of ticketing system to restake and restake_all
- Withdrawal Changes: withdraw_all accepting optional product arguments
- Codebase refactor: Moving non-NEAR related code to the models folder. High level review
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
- 01 Likelihood Likely, possible or rare
- 02 Impact Severe, moderate or negligible
- 03 Severity Derived from the matrix below
- 04 Remediation complexity Simple, moderate or difficult
- 05 Status Not fixed, fixed, acknowledged or scheduled
Impact
| Impact | What it means here |
|---|---|
| Severe | Exploitation could result in critical loss or compromise, such as full system control, substantial financial loss, or severe reputational damage. |
| Moderate | Exploitation may lead to limited data loss, partial compromise, moderate financial impact, or noticeable degradation of services. |
| Negligible | Exploitation has minimal impact, such as minor data exposure without significant consequences or slight inconvenience without substantial disruption. |
Likelihood
| Likelihood | What it means here |
|---|---|
| Likely | The vulnerability is easily discoverable and not overly complex to exploit. |
| Possible | The vulnerability presents some challenges either in discovery or in the complexity of the attack. |
| Rare | The 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 Ease | Obvious | Concealed | Hidden |
|---|---|---|---|
| Complex | Possible | Rare | Rare |
| Moderate | Likely | Possible | Rare |
| Straightforward | Likely | Possible | Possible |
Severity
| Severity | What it means here |
|---|---|
| Critical | Assigned to vulnerabilities with severe impact and a likely likelihood of exploitation. |
| High | For vulnerabilities with either severe impact but only a possible likelihood, or moderate impact with a likely likelihood. |
| Medium | Used for vulnerabilities with severe impact but a rare likelihood, moderate impact with a possible likelihood, or negligible impact with a likely likelihood. |
| Low | For vulnerabilities with moderate impact and rare likelihood, or negligible impact with a possible likelihood. |
| Informational | The lowest severity rating, typically for vulnerabilities with negligible impact and a rare likelihood of exploitation. |
| Likelihood \ Impact | Severe | Moderate | Negligible |
|---|---|---|---|
| Likely | Critical | High | Medium |
| Possible | High | Medium | Low |
| Rare | Medium | Low | Informational |
Remediation complexity
This measures how difficult it is to remediate a finding once it has been identified.
| Remediation complexity | What it means here |
|---|---|
| Simple | Patches or fixes are readily available and easily implemented. |
| Moderate | Requires some time and resources to remediate, but well within the capabilities of most organizations. |
| Difficult | Remediation 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.
| Status | What it means here |
|---|---|
| Not Fixed | Indicates 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. |
| Fixed | This 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. |
| Acknowledged | This 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. |
| Scheduled | This 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
Findings register
| Finding | Impact | Likelihood | Severity | Remediation complexity | Status |
|---|---|---|---|---|---|
| GUV-1: Possible Double Claim Through Race Condition | Severe | Rare | Medium | Simple | Fixed |
| GUV-2: Cross Function Ticket Reuse | Negligible | Rare | Informational | Simple | Fixed |
Detailed Findings
GUV-1: Possible Double Claim Through Race Condition
Description
We observed that it is not verified whether a user is in migrating state through assert_account_is_not_migrating in any of the state changing functions like claim/withdraw/restake in old contract. Since the account is deleted only inside of the after_account_transferred, there is a time for a malicious actor to call claim to claim accumulated amount and then after the account is deleted, call claim again on a new migrated smart contract to claim twice.
pub fn after_account_transferred(&mut self, account_id: AccountId) -> PromiseOrValue<(AccountId, bool)> {let is_success = is_promise_success(); if is_success { self.clear_account(&account_id); emit(EventKind::JarsMerge(account_id.clone()));}... Recommendation
Consider asserting the assert_account_is_not_migrating in all state mutating functions.
Remediation
The Sweat Foundation team has fixed the issue by adding the assert_account_is_not_migrating in all state mutating functions in this commit: 89755f5cfbac88764131560ec1d0085464f58cc9
GUV-2: Cross Function Ticket Reuse
Description
We observed that it is possible to generate a ticket with a signature for jar creation but supply it to the restake and restake_all functions. Depending on logic of both functions, it can introduce security issues in the future and in general it increases the attack surface.
fn restake( &mut self, from: ProductId, ticket: DepositTicket, signature: Option<Base64VecU8>, amount: Option<U128>,) -> PromiseOrValue<()> { pub(crate) fn create_jar( &mut self, account_id: AccountId, ticket: JarTicket, amount: U128, signature: Option<Base64VecU8>,) -> JarView Recommendation
Consider disallowing cross-function ticket reuse.
Remediation
The Sweat Foundation team has fixed the issue by introducing purpose in deposit message in this commit and update on the backend: fd72e8cb72af66eb254d90c173387bf8236e61f3
The web version and the PDF (13 pages) are generated from the same source. The report as first delivered is kept in the public reports archive.