- All findings
- 4
- Critical
- 0
- High
- 0
- Medium
- 0
- Low
- 1
- Informational
- 3
Date of engagement: 29th December 2025 - 12th January 2026
About Us
Guvenkaya is a security research firm specializing in Rust security, Web3 security of Non-EVM protocols, and Web2 security. With our expertise, we provide both security auditing services and custom security solutions
About The Sweat
Foundation 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.
Audit Results
Guvenkaya conducted a security assessment of the SWEAT Jar code changes introduced in PR #144 (Tiered Score Based Jars & Boosters). During this engagement, 4 findings were reported: 1 Low and 3 Informational severity issues. The Low finding highlights possible arithmetic overflow paths, while the Informational findings cover APY representation constraints, booster lifecycle edge-cases, and global APY clamping behavior.
Project Scope
SWEAT Jar (PR #144)
| Files | Link |
|---|---|
| Tiered Score Based Jars & Boosters | https://github.com/Sweat-Foundation/sweat-jar/pull/144 |
Out of Scope
The audit included reviewing the code changes in scope for security vulnerabilities, coding practices, and architecture. The audit does not include a review of external dependencies, off-chain services, or oracle infrastructure beyond how they are consumed by the smart contracts.
Timeline
- Start of the audit
29th December 2025
- Draft report
12th January 2026
- Final report
14th January 2026
Methodology
- RESEARCH INTO PROJECT ARCHITECTURE
- PREPARING ATTACK VECTORS
- SETTING UP AN ENVIRONMENT
- MANUAL CODE REVIEW OF THE CODE
- ASSESSMENT OF RUST SECURITY ISSUES
- ASSESSMENT OF NEAR SECURITY ISSUES
- ASSESSMENT OF ARITHMETIC ISSUES
- BUSINESS LOGIC VULNERABILITY ASSESSMENT
- ONCHAIN TESTING USING NEAR WORKSPACES
- BEST PRACTICES AND CODE QUALITY
- CHECKING FOR CODE REFACTORING/SIMPLIFICATION POSSIBILITIES
- ARCHITECTURE IMPROVEMENT SUGGESTIONS
- PREPARING POCS AND/OR TESTS FOR EACH CRITICAL/HIGH/MEDIUM ISSUES
Severity Breakdown
Findings Summary
| Finding | Impact | Likelihood | Severity | Remediation complexity | Remediation status |
|---|---|---|---|---|---|
| GUV-1: Possible overflows | Moderate | Rare | Low | Simple | Fixed |
| GUV-2: Possible misinterpretation of the APY value. | Negligible | Rare | Informational | Moderate | Fixed |
| GUV-3: Possible Booster lifecycle panic | Negligible | Rare | Informational | Simple | Fixed |
| GUV-4: Inconsistent global APY clamping | Negligible | Rare | Informational | Simple | Fixed |
Findings Details
GUV-1: Possible overflows
LowIf the booster is active, the DailyScore::to_capped_apy calculates the `self.value.min(cap) + self.booster`, each individual component being a `u16` types. When added together, they might overflow, if their sum is bigger than `u16::MAX`. The contract enables overflow-checks so whenever it would be encounter, the contract will panic instead.
model/src/data/score/mod.rs:to_capped_apy
pub fn to_capped_apy(&self, cap: Score, include_booster: bool) -> UDecimal {
(self.value.min(cap) + if include_booster { self.booster } else { 0 }).to_apy()
}Another case is of a possible overflow is in get_interest function. It calculates the interest as `term_in_milliseconds * apy * principal` using `u128` type. That type can contain large numbers, so an actual overflow in production environment is not likely, but still possible given the right combination of values.
Recommendation
It is recommended to use the the `saturating_` variants of mathematical operations to make sure overflow is not encountered.
Remediation - Fixed
The Sweat Foundation team has fixed the issue in this commit: 607f3f61ab38faed74fe23e16ee825a55c289f17
GUV-2: Possible misinterpretation of the APY value.
Informational100% APY (as indicated in the PR docs) seems to not be possible due to type constraints
The APY is represented as `u16` which is then converted to `UDecimal` type. The "encoding" makes 1% = 1000. Since `u16`'s max value is ~65k, the max APY that can be represented is about 65.5%. This, however, might not be an issue, depending if the PR description is correct.
Recommendation
An altnerative type representing the Score can be considered, `u32` will be able to represent the whole range of per-cent values using the current encoding.
Remediation - Fixed
The Sweat Foundation team has fixed the issue in this commit: 607f3f61ab38faed74fe23e16ee825a55c289f17
GUV-3: Possible Booster lifecycle panic
InformationalFirst, the booster timestamp might case a panic within the contract if it's older than `DAYS_STORED` in the past. This panic requires an oracle to pass an older-than-expected value, which possibly is not expected to happen, however for resiliency, it would be advised to not panic, and instead simply ignore those values.
Recommendation
We recommend gracefully handling the errorouns cases here instead of panicing.
Remediation - Fixed
The Sweat Foundation team has fixed the issue in these commits: 3f60fa06e1530aa743e6d230cb028deede60614e and 8abef8c4b010de7a9aa8ba9be38da000adda98b5
GUV-4: Inconsistent global APY clamping
InformationalThe current APY cap is implemented as capping the value and adding booster ontop of it, which might increase the total APY to be above the defined cap. This might be intended, however. Documentation suggests that it's not.
Recommendation
We recommend double checking the design to make sure which approach is the intended one and changing the implementation (if needed) accordingly - making the cap act on a sum of actual value with a booster.
Remediation - Fixed
The Sweat Foundation team has fixed the issue in this commit: 607f3f61ab38faed74fe23e16ee825a55c289f17
Source: published GitHub report · 14 pages. The original PDF includes the source formatting, figures, and linked references.
